从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可能不是一个好名字。 当有人必须出现并维护您的代码时,它可能会引起混淆。