从C中的内联汇编程序中定义的访问数组
我在Assembler中声明了一个整数,我在C中以下列方式使用它:
asm( "number: \n" ".long 0xFFFFFFFF \n ); extern int number; int main(){ //do something with number }
现在我想在Assembler中声明一个32字节的数组。 我尝试了以下方法:
asm( "number: \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ); extern unsigned char* number; int main() { printf("%x ", number[0]); //gives segmentation fault }
我真的不知道汇编程序,但我必须使用这个特定的变量。
你的内联汇编程序就是这样做的
asm( "number: \n" ".long 0xFFFFFFFF \n" [snip rest of array] );
然后你告诉C那个数字是
extern unsigned char* number;
这表示该数字是指向无符号字符的指针。 然后你这样访问它:
printf("%x ", number[0]);
这表示在数字中取消引用指针并返回第一个字符。 这与做的一样:
printf("%x ", *(number+0));
问题是该数字被定义为指针。 假设32位指针转换为:
*(0xFFFFFFFF+0)
如果你遇到段错误,可能是因为你的程序无法访问地址0xFFFFFFFF。
您可以将外部语句更改为:
extern unsigned char number[32];
现在number是一个包含32个无符号字符的数组。 我倾向于使用inttypes.h
标头并将其声明为:
extern uint8_t number[32];
uint8_t
保证为8位(或1个字节)。 另一方面, char
被定义为最少8位(但可以更多)。 但是sizeof(char)
将始终返回1.我更喜欢uint8_t
(无符号8位整数),因此您知道您正在处理8位值,这似乎就是这里的情况。 我将代码修改为:
#include #include __asm__( "number: \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFE \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ".long 0xFFFFFFFF \n" ); extern uint8_t number[32]; int main() { printf("%x ", number[0]); return 0; }
另请注意,如果您打算使用GCC编译为C99(也适用于GCC的C89),最好使用__asm__
而不是asm
因为GCC的默认设置是在使用-std=c99
时禁用asm
关键字(除非用-fasm
覆盖) -std=c99
选项。
对于无符号字符数组, number可能不是一个好名字。 当有人必须出现并维护您的代码时,它可能会引起混淆。