- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
上下文:
我正在研究 ARM 目标,更具体地说是 ST 的 Cortex-M4F 微 Controller 。在这样的平台(一般是微 Controller )上工作时,显然没有操作系统;为了获得一个工作的 C/C++“环境”(此外,为了在变量初始化方面符合标准)必须有某种启动代码在重置时运行,在显式调用 main 之前执行所需的最少设置
。正如我所暗示的,这样的启动代码必须初始化已初始化的全局变量和静态变量(例如 int foo = 42;
在全局范围内)并将其他全局变量清零(例如 int bar;
在全局范围内)。然后,如有必要,将调用全局“参与者”。
在微 Controller 上,这仅仅意味着启动代码必须为每个初始化的全局变量(全部在“.data”部分)将数据从闪存复制到 ram,并清除其他(全部在“.bss”部分)。因为我使用 GCC,所以我必须提供这样的启动代码,并且我很高兴地分析了几个启动代码(及其关联的链接器脚本!)与我在 Internet 上找到的大量示例捆绑在一起,所有示例都使用我正在开发的相同演示板.
问题:
如前所述,我见过许多启动代码,它们以不同的方式初始化全局变量,其中一些在空间和时间方面比其他方式更有效。但它们都有一些奇怪的共同点:它们没有使用memset
或memcpy
,而是求助于手写循环来完成这项工作.因为在可能的情况下使用标准函数对我来说很自然(简单的“DRY 原则”),所以我尝试了以下方法来代替最初的手写循环:
/* Initialize .data section */
ldr r0, DATA_LOAD
ldr r1, DATA_START
ldr r2, DATA_SIZE
bl memcpy /* memcpy(DATA_LOAD, DATA_START, DATA_SIZE); */
/* Initialize .bss section */
ldr r0, BSS_START
mov r1, #0
ldr r2, BSS_SIZE
bl memset /* memset(BSS_START, 0, BSS_SIZE); */
...而且效果很好。节省的空间可以忽略不计,但现在显然非常简单。
所以,我考虑了一下,我认为在这种情况下没有理由手写循环:
memcpy
和 memset
很可能无论如何都链接到可执行文件中,因为程序员会直接使用它,或通过另一个库间接使用它;知道为什么人们不依赖于 memcpy
和 memset
作为启动代码吗?
最佳答案
我怀疑启动代码不想对 libc 中的 memcpy
等的实现做出假设。例如,memcpy
的实现可能会使用由 libc 初始化代码设置的全局变量来报告可用的 cpu 扩展,以便在支持此类操作的机器上提供优化的 SIMD 复制。在早期的“crt”启动代码运行时,这样一个全局的存储可能完全未初始化(包含随机垃圾),在这种情况下调用 memcpy
是危险的。即使使调用对你有效,这也是实现(或者甚至可能是 UB 的不可预测的结果......)使其有效的结果;这可能不是 crt 代码想要依赖的东西。
关于c - 嵌入式:大多数 CRT 启动代码不使用 memcpy/memset——为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15456999/
在互联网上浏览代码时,我经常看到这样的片段: struct epoll_event event; memset(&event, 0, sizeof(event)); 如果事件填写完整,这种模式对我来说
我不认为我在这里理解了什么...... bool (*lookup)[100]; memset(lookup, 0, 100 * sizeof(*lookup)); 我正在尝试初始化一个指向堆栈分配数
我从以前退休的开发人员那里继承了一些代码。我的问题具体是在以下场景中使用 memset。不是 c 程序员,我想知道为什么在这种特殊情况下使用 memset,其中下一行代码将值存储在刚刚被 memset
如何在 jsctypes 中使用 memset。没有对应的 DLL。我搜索/搜索了 js ctype 代码,但找不到要破解的示例。 最佳答案 如果您只想将数组memset为零字节,那么我有“好消息,大
在尝试重新创建“memset”函数时,如果我尝试取消引用 void 指针,或者第二个参数的类型与第一个参数的类型不同,则会出现错误。为了使该功能正常工作,我必须将其更改为: void ft_memse
我关注了How to memset char array with null terminating character?在使用 C memset api 时添加空终止符。 代码有效;由于空终止符,我
这个问题在这里已经有了答案: Calloc with structure with pointers in C (3 个答案) 关闭 7 年前。 考虑以下对 void 指针数组的初始化: #incl
我写了这段代码: #include int main(void) { char c[10]=""; //Q if(c[2]=='\0')
我正在尝试为 2D 矩阵分配内存,但出现段错误。 int** inicializarMatriz(int **matriz, int vertices){ int i; matriz=(int**)
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
这给我带来了 memset 的段错误,我不知道为什么,我要访问 2D 数组的特定索引,这应该给我一个 char 指针并允许我使用 memeset。 void test(char** test) {
我正在尝试增长一个数组以添加新的 malloc 指针。 realloc 似乎并没有增加大小。另外,我一开始就为数组中的一个指针提供了足够的空间,因此即使 realloc 没有增加大小,我仍然希望能够复
我正在用 C 语言做一个关于 UDP 套接字的练习。当客户端发送特定消息(例如 hi)时,服务器必须发送“很高兴见到你”。如果没有找到标准回复,服务器将发送“没有合适的回复”。我的问题是memset如
由于memset采用字符串或数组的地址并将它们视为字符缓冲区。 它如何知道必须分配的给定值应该以 1 字节(字符)为一组还是以 4 字节为一组进行分配(整数)。 最佳答案 但事实并非如此。在第三个参数
我想避免使用memset()在这样的结构上: typedef struct { int size; float param1; } StructA; typedef struct {
我有以下一组代码,无法找到为什么我得到垃圾值。我的目的是将字节数复制为目标,而不考虑源,以便为我的应用程序制作通用副本。但没有得到正确的结果。有什么办法可以实现这一点。 int main() {
我定义了一个结构体,以及一个接受结构体指针并填充相关信息的函数,同时在开始时进行空检查。 粗略示例: typedef struct { int field; } myStruct; void my
我在编写一个函数来从文件中提取字符串作为更大程序的一部分时遇到一些问题。一切似乎都工作正常,除了当我使用 memset 或 bzero 来删除我一直在使用的字符数组时。我已经解决这个问题一个多小时了,
void readdat (int c, char **v) { char *dc; char *pdc; dc = malloc((line+1) * sizeof(char)); memset(d
我有一个指向数组的指针。我知道该数组可以容纳多少个项目,但每个项目的长度是动态的。那么在这种情况下如何memset()数组。 Int8 *data[4]; //array can hold maxim
我是一名优秀的程序员,十分优秀!