Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
memcpy()用于裸机环境_C_Memcpy_Bare Metal - Fatal编程技术网

memcpy()用于裸机环境

memcpy()用于裸机环境,c,memcpy,bare-metal,C,Memcpy,Bare Metal,这更像是一种好奇心。但我想知道,在裸机环境中实现memcpy() #定义我的内存(DST、SRC、大小)\ {struct tmp{char mem[SIZE];};*((struct tmp*)((void*)DST))=*((struct tmp*)((void*)SRC));} 然后我们可以使用 #包括 #定义我的内存(DST、SRC、大小)\ {struct tmp{char mem[SIZE];};*((struct tmp*)((void*)DST))=*((struct tmp*

这更像是一种好奇心。但我想知道,在裸机环境中实现
memcpy()

#定义我的内存(DST、SRC、大小)\
{struct tmp{char mem[SIZE];};*((struct tmp*)((void*)DST))=*((struct tmp*)((void*)SRC));}
然后我们可以使用

#包括
#定义我的内存(DST、SRC、大小)\
{struct tmp{char mem[SIZE];};*((struct tmp*)((void*)DST))=*((struct tmp*)((void*)SRC));}
int main(){
字符缓冲区[100]=“你好世界”;
printf(“%s\n”,缓冲区);
MY_MEMCPY(缓冲区,“一”,4)
printf(“%s\n”,缓冲区);
MY_MEMCPY(缓冲区,“2”,4)
printf(“%s\n”,缓冲区);
MY_MEMCPY(缓冲区,“三”,6)
printf(“%s\n”,缓冲区);
返回0;
}
哪张照片

Hello world
one
two
three
据我所知,它不会违反严格的别名规则,因为指向
struct
的指针始终等于指向其第一个成员的指针,在这种情况下,第一个成员是
char
。见:

经过适当转换的结构对象指针指向其初始成员(如果该成员是位字段,则指向其所在的单元),反之亦然

它也不会有对齐问题,因为它的
\u Alignof()
1

进一步阅读:

编辑#1

仅对于文字字符串,我们可以创建宏的另一个版本,该版本不需要任何长度作为参数传递。当然,目标仍然需要有足够的内存来保存新字符串

以下是修改后的版本:

/*
**警告**只有当'SRC'是**文字字符串**或
在所有其他情况下,其大小可以使用`sizeof()计算`
*/
#定义MY_LITERAL_MEMCPY(DST、SRC)\
{struct tmp{char mem[sizeof(SRC)];};*((struct tmp*)((void*)DST))=*((struct tmp*)((void*)SRC));}
我们可以使用

#包括
/*
**警告**只有当'SRC'是**文字字符串**或
在所有其他情况下,其大小可以使用`sizeof()计算`
*/
#定义MY_LITERAL_MEMCPY(DST、SRC)\
{struct tmp{char mem[sizeof(SRC)];};*((struct tmp*)((void*)DST))=*((struct tmp*)((void*)SRC));}
int main(){
字符缓冲区[100]=“你好世界”;
printf(“%s\n”,缓冲区);
MY_LITERAL_MEMCPY(缓冲区,“一”)
printf(“%s\n”,缓冲区);
MY_LITERAL_MEMCPY(缓冲区,“两个”)
printf(“%s\n”,缓冲区);
MY_LITERAL_MEMCPY(缓冲区,“三”)
printf(“%s\n”,缓冲区);
返回0;
}
编辑#2

如果您担心假想的外来编译器可能添加的任何填充,添加
\u Static\u assert()
将使宏非常安全:

MY_MEMCPY()

#定义我的内存(DST、SRC、大小)\
{struct tmp{char mem[SIZE];};_Static_assert(sizeof(struct tmp))\
==大小,“你有一个非常愚蠢的编译器”)\
*((结构tmp*)((void*)DST))=*((结构tmp*)((void*)SRC));}
MY\u LITERAL\u MEMCPY()

/*
**警告**只有当'SRC'是**文字字符串**或
在所有其他情况下,其大小可以使用`sizeof()计算`
*/
#定义MY_LITERAL_MEMCPY(DST、SRC)\
{struct tmp{char mem[sizeof(SRC)];};_Static_assert(sizeof(struct tmp)\
==sizeof(SRC),“你有一个非常愚蠢的编译器”)\
*((结构tmp*)((void*)DST))=*((结构tmp*)((void*)SRC));}
编辑#3

关于法典合法性的讨论

如果将任何内存位置强制转换为
char*
是合法的,那么我们可以将非
char
类型的每个字节映射到不同的
char*
变量:

一些非字符类型的测试;
字符*一=(字符*)&测试;
char*two=(char*)&test+1;
字符*三=(字符*)&测试+2;
...
char*last=(char*)&test+sizeof(test)-1;
如果上面的代码是合法的,那么将上面的所有字节集中映射到单个
char
数组也是合法的,因为我们正在映射相邻的字节:

char(*所有字符)[sizeof(一些非字符类型)]=(char(*)[sizeof(一些非字符类型)]&测试;
在这种情况下,我们将以
(*all of them)[0]
(*all of them)[1]
(*all of them)[2]
等方式访问它们

如果将相邻字节的集合映射到
char
数组是合法的,那么将该数组转换为单个成员聚合类型也是合法的,前提是编译器不向后者添加填充:

struct tmp{
char mem[sizeof(某些非char类型)];
};
_静态断言(sizeof(struct tmp)==sizeof(某些非字符类型),
“你有一个非常愚蠢的编译器”);
struct tmp*wrap=(struct tmp*)和test;
编辑#4

这是对Nate Eldredge的回答——因为似乎启用了优化后,编译器可能会做出错误的假设。在将数据复制到
DST
之前,只需添加一个简单的
*((char*)DST)=0,就可以明确地告诉编译器我们的别名。以下是启用了优化的宏的新版本:

MY_MEMCPY()

#定义我的内存(DST、SRC、大小)\
{struct tmp{char mem[SIZE];};_Static_assert(sizeof(struct tmp))\
==SIZE,“你有一个非常愚蠢的编译器”);*((char*)DST)=0\
*((结构tmp*)((void*)DST))=*((结构tmp*)((void*)SRC));}
MY\u LITERAL\u MEMCPY():

/*
**警告**只有当'SRC'是**文字字符串**或
在所有其他情况下,其大小可以使用`sizeof()计算`
*/
#定义MY_LITERAL_MEMCPY(DST、SRC)\
{struct tmp{char me
#include <string.h>
#include <stdio.h>

#define SIZE 50
#define STRUCT_COPY 

#ifdef STRUCT_COPY
// your proposed macro
#define MY_MEMCPY(DST, SRC, SIZE) \
    { struct tmp { char mem[SIZE]; }; _Static_assert(sizeof(struct tmp) \
    == SIZE, "You have a very stupid compiler"); \
    *((struct tmp *) ((void *) DST)) = *((struct tmp *) ((void *) SRC)); }
#else
#define MY_MEMCPY memcpy
#endif


void foo(int *x, void *a, void *b) {
    (*x)++;
    MY_MEMCPY(a, b, SIZE * sizeof(int));
    (*x)++;
}

int a[SIZE], b[SIZE];

int main(void) {
    a[0] = 10;
    b[0] = 20;
    foo(&a[0], a, b);
    printf("a[0] = %d", a[0]);
}