2

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.

5
  • 1
    Declaration is not enough. You need to define it. And: you cannot define an integer in Assembler; Assembler does not have a concept of datatypes. And if that shall be 32 bit data, you do you declare it in your C code as char? (And "I have to use ... someone pointing a gun at you?) Commented Nov 4, 2015 at 11:51
  • Why did you think unsigned char * was right? That doesn't make any sense to me, at all. Perhaps extern int number[8]; but I'm really out on a limb here. Commented Nov 4, 2015 at 11:53
  • If you declare unsigned char *number, that means the value at the location number represents holds an address or a pointer. In this case, that address or pointer is 0xFFFFFFFF. Then when you dereference it as number[0], you are attempting to reference whatever is at address 0xFFFFFFFF, which is invalid. Try "number: my_array\n" followed by "my_array:\n" prefacing your list of .long` values. Or try the method @unwind suggested. Commented Nov 4, 2015 at 11:55
  • Do you want a 32 byte value or 32 bit value? Commented Nov 4, 2015 at 13:35
  • @Linus, 32 byte. Based on unwind's comment I declared it as extern unsigned char number[32]. Commented Nov 4, 2015 at 13:39

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.