简体   繁体   English

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

[英]Access array defined in inline assembler from C

I have an integer declared in Assembler, and I use it in C in the following way:我在汇编程序中声明了一个整数,我在 C 中按以下方式使用它:

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

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

Now I want to declare a 32 byte array in Assembler.现在我想在汇编程序中声明一个 32 字节的数组。 I tried the following:我尝试了以下方法:

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
}

I do not really know Assembler, but I have to use for this specific variable.我不太了解汇编程序,但我必须使用这个特定的变量。

Your inline assembler does this您的内联汇编器执行此操作

asm(
            "number:    \n"
            ".long 0xFFFFFFFF \n"
            [snip rest of array]
);

You then tell C that number is然后你告诉C这个数字

extern unsigned char* number;

This says that number is a pointer to an unsigned character.这表示该数字是指向无符号字符的指针。 Then you access it like this:然后你像这样访问它:

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

This says to de-reference the pointer in number and return the first character.这表示取消引用number 中的指针并返回第一个字符。 It would have been the same as doing:这将与执行相同:

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

Problem is that number was defined as a pointer.问题是数字被定义为一个指针。 Assuming 32-bit pointers that translates to:假设 32 位指针转换为:

*(0xFFFFFFFF+0)

If you get a segfault it is probably because the address 0xFFFFFFFF is not accessible to your program.如果出现段错误,可能是因为您的程序无法访问地址 0xFFFFFFFF。

You can change your extern statement to read:您可以将extern语句更改为:

extern unsigned char number[32];

Now number is an array of 32 unsigned characters.现在number是一个包含 32 个无符号字符的数组。 I'd be inclined to use the inttypes.h header and declare it as:我倾向于使用inttypes.h标头并将其声明为:

extern uint8_t number[32];

uint8_t is guaranteed to be 8 bits (or 1 byte). uint8_t保证为 8 位(或 1 个字节)。 char on the other hand is defined as being a minimum of 8 bits (but can be more).另一方面, char被定义为最少 8 位(但可以更多)。 However sizeof(char) will always return 1. I prefer uint8_t (unsigned 8 bit integers) just so you know you are dealing with 8 bit values which seems to be the case here.但是sizeof(char)将始终返回 1。我更喜欢uint8_t (无符号 8 位整数),这样您就知道您正在处理 8 位值,这里似乎就是这种情况。 I'd modify the code to be:我将代码修改为:

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

Also note that if you intend to compile using GCC as C99 (will work with GCC's C89 as well) it is preferable to use __asm__ instead of asm since GCC's default is to disable the asm keyword (unless overridden with -fasm ) when using -std=c99 option.另请注意,如果您打算使用 GCC 作为 C99 进行编译(也适用于 GCC 的 C89),最好使用__asm__而不是asm因为 GCC 的默认值是在使用-std=c99时禁用asm关键字(除非被-fasm覆盖) -std=c99选项。

number is probably not a good name for an array of unsigned characters. number可能不是一个无符号字符数组的好名字。 It may cause confusion when someone has to come along and maintain your code.当有人必须出现并维护您的代码时,这可能会引起混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM