c - 从 C 访问内联汇编器中定义的数组

标签 c gcc assembly x86 inline-assembly

我在汇编器中声明了一个整数,并按以下方式在 C 中使用它:

asm(
            "number:    \n"
            ".long 0xFFFFFFFF \n
);

extern int number;
int main(){
    //do something with number
}

现在我想在汇编器中声明一个 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;

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

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

这表示取消引用 number 中的指针并返回第一个字符。这与执行以下操作相同:

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

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

*(0xFFFFFFFF+0)

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

您可以将 extern 语句更改为:

extern unsigned char number[32];

现在number是一个由32个无符号字符组成的数组。我倾向于使用 inttypes.h header 并将其声明为:

extern uint8_t number[32];

uint8_t 保证为 8 位(或 1 个字节)。另一方面,char 被定义为至少 8 位(但可以更多)。但是 sizeof(char) 将始终返回 1。我更喜欢 uint8_t (无符号 8 位整数),这样您就知道您正在处理 8 位值,这似乎是这种情况这里。我将代码修改为:

#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;
}

另请注意,如果您打算使用 GCC 作为 C99 进行编译(也可以与 GCC 的 C89 一起使用),最好使用 __asm__ 而不是 asm,因为 GCC 的默认值是在使用 -std=c99 选项时禁用 asm 关键字(除非被 -fasm 覆盖)。

number 对于无符号字符数组来说可能不是一个好名字。当必须有人来维护您的代码时,这可能会引起困惑。

关于c - 从 C 访问内联汇编器中定义的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33521099/

相关文章:

c - 箭头指出 C 中用户的错误输入

ubuntu - 尝试在 Ubuntu 上使用 gcc 构建胖通用二进制文件时出错

c - 网络的机器代码是什么样的?

c++ - 使用 C++ 库

c - 关闭套接字的问题

c - 为什么 getline 的第一个参数是指向指针 "char**"而不是 "char*"的指针?

python - 汇编 x86 "PSHUFB 128bit"另一种语言的实现

linux - 更改 FPU 舍入模式

c - 如何以原始用户身份从 sudo 程序中执行命令?

c++ - gcc 和 clang 是否没有正确推断模板别名类型?