bholanath
bholanath

Reputation: 1753

Unable to access correct global label data of assembly from C in linux

I have an assembly code (hello1.s) where global label A_Td is defined and I want to access all the long data values defined with global label A_Td from/inside C program.

.file   "hello1.s"
.globl  A_Td
.text
.align  64
A_Td:
    .long   1353184337,1353184337
    .long   1399144830,1399144830
    .long   3282310938,3282310938
    .long   2522752826,2522752826
    .long   3412831035,3412831035
    .long   4047871263,4047871263
    .long   2874735276,2874735276   
    .long   2466505547,2466505547

As A_Td is defined in text section, so it is placed in code section and only one copy is loaded into memory.

Using yasm , I have generated hello1.o file

yasm -p gas -f elf32 hello1.s 

Now, to access all the long data using global label A_Td , I have written following C code (test_glob.c) taking clue from here global label.

//test_glob.c
extern A_Td ;

int main()
{
    long *p;
    int i;
    p=(long *)(&A_Td);
    for(i=0;i<16;i++)
    {
        printf("p+%d %p %ld\n",i, p+i,*(p+i));
    }
    return 0;
}

Using following command I have compiled C program and then run the C code.

gcc hello1.o test_glob.c 
./a.out

I am getting following output

p+0 0x8048400 1353184337
p+1 0x8048404 1353184337
p+2 0x8048408 1399144830
p+3 0x804840c 1399144830  -----> correct till this place
p+4 0x8048410 -1012656358 -----> incorrect value retrieved from this place
p+5 0x8048414 -1012656358
p+6 0x8048418 -1772214470
p+7 0x804841c -1772214470
p+8 0x8048420 -882136261
p+9 0x8048424 -882136261
p+10 0x8048428 -247096033
p+11 0x804842c -247096033
p+12 0x8048430 -1420232020
p+13 0x8048434 -1420232020
p+14 0x8048438 -1828461749
p+15 0x804843c -1828461749

ONLY first 4 long values are correctly accessed from C program. Why this is happening ?

What needs to be done inside C program to access the rest of data correctly ?

I am using Linux. Any help to resolve this issue or any link will be a great help. Thanks in advance.

Upvotes: 2

Views: 200

Answers (1)

FrankPl
FrankPl

Reputation: 591

How many bytes does "long" have in this system?

It seems to me that printf interprets the numbers as four byte signed integers, where the value 3282310938 has the hex value C3A4171A, which is above 7FFFFFFF (in decimal: 2147483647) which is the largest four byte positive signed number, and hence a negative value -1012656358. I assume that the assembler just interprets these four byte numbers as unsigned.

If you would use %lu instead of %ld, printf would interpret the numbers as unsigned, and should show what you expected.

Upvotes: 1

Related Questions