Reputation: 3726
I have an integer declared in Assembler, and I use it in C in the following way:
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. 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.
Upvotes: 2
Views: 915
Reputation: 47573
Your inline assembler does this
asm(
"number: \n"
".long 0xFFFFFFFF \n"
[snip rest of array]
);
You then tell C that number is
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. 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:
*(0xFFFFFFFF+0)
If you get a segfault it is probably because the address 0xFFFFFFFF is not accessible to your program.
You can change your extern statement to read:
extern unsigned char number[32];
Now number is an array of 32 unsigned characters. I'd be inclined to use the inttypes.h
header and declare it as:
extern uint8_t number[32];
uint8_t
is guaranteed to be 8 bits (or 1 byte). char
on the other hand is defined as being a minimum of 8 bits (but can be more). 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. 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.
number is probably not a good name for an array of unsigned characters. It may cause confusion when someone has to come along and maintain your code.
Upvotes: 2