从C在内联汇编程序中定义的访问数组

时间:2015-11-04 11:49:27

标签: c assembly

我在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
}

我真的不知道汇编程序,但我必须使用这个特定的变量。

1 个答案:

答案 0 :(得分:2)

您的内联汇编程序执行此操作

extern unsigned char* number;

然后告诉 C

printf("%x ", number[0]);

这表示 number 是指向无符号字符的指针。然后你这样访问它:

printf("%x ", *(number+0));

这表示取消引用 number 中的指针并返回第一个字符。这与做的一样:

*(0xFFFFFFFF+0)

问题是 number 被定义为指针。假设32位指针转换为:

extern unsigned char number[32];

如果您遇到段错误,可能是因为您的程序无法访问地址0xFFFFFFFF。

您可以将 extern 语句更改为:

inttypes.h

现在 number 是一个包含32个无符号字符的数组。我倾向于使用extern uint8_t number[32]; 标题并将其声明为:

uint8_t

char保证为8位(或1个字节)。另一方面,sizeof(char)被定义为最少8位(但可以更多)。但是uint8_t将始终返回1.我更喜欢#include <stdio.h> #include <inttypes.h> __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; } (无符号8位整数),因此您知道您正在处理8位值,这似乎就是这里的情况。我将代码修改为:

__asm__

另请注意,如果您打算使用GCC作为C99进行编译(也适用于GCC&#39; C89),最好使用asm代替asm,因为GCC&#39;默认设置是在使用-fasm选项时禁用-std=c99关键字(除非被null覆盖)。

对于无符号字符数组,

number 可能不是一个好名字。当某人必须出现并维护您的代码时,它可能会引起混淆。