无法在linux中从C访问程序集的正确全局标签数据

无法在linux中从C访问程序集的正确全局标签数据,c,linux,assembly,embedded-linux,C,Linux,Assembly,Embedded Linux,我有一个汇编代码(hello1.s),其中定义了全局标签A_Td,我想从C程序中/从C程序中访问使用全局标签A_Td定义的所有长数据值 .file "hello1.s" .globl A_Td .text .align 64 A_Td: .long 1353184337,1353184337 .long 1399144830,1399144830 .long 3282310938,3282310938 .long 2522752826,25

我有一个汇编代码(hello1.s),其中定义了全局标签A_Td,我想从C程序中/从C程序中访问使用全局标签A_Td定义的所有长数据值

.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
由于在文本部分中定义了一个\u Td,因此它被放置在代码部分中,并且只有一个副本被加载到内存中

使用yasm,我生成了hello1.o文件

yasm -p gas -f elf32 hello1.s 
现在,为了使用global labelA_Td访问所有长数据,我编写了以下C代码(test_glob.C),从这里获取线索

我得到以下输出

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
C程序只能正确访问前4个长值。为什么会发生这种情况?

在C程序内部需要做什么才能正确访问其余数据?

我正在使用Linux。解决这个问题的任何帮助或任何链接都将是巨大的帮助。提前谢谢。

这个系统中“long”有多少字节

在我看来,printf将数字解释为四字节有符号整数,其中值
3282310938
具有十六进制值
C3A4171A
,该值高于
7FFFFFFF
(十进制:2147483647),这是最大的四字节正符号数,因此为负值
-1012656358
。 我假设汇编程序只是将这些四字节的数字解释为无符号的


如果您使用
%lu
而不是
%ld
,printf会将数字解释为无符号,并应显示您的预期值。

@FrankPI,在我的系统中,sizeof(long)返回4,表示long需要4字节。@bholanath:有符号32位int的最小值和最大值是多少?@FrankPI,正如您使用%lx而不是%ld指出的那样,我得到了正确的十六进制值。谢谢您的及时回答。@FrankPI,是的,使用%lu给出了正确的输出。@bholanath:
。x86气体组件中的long
始终为32位,即使C
long
为64位。你在这里很幸运,但你需要阅读你的汇编程序手册。e、 g.说它是
.int
的同义词,大小和字节顺序取决于目标
.quad
是8个字节。嗯,我真的找不到它是否说x86的
.long
是4字节。你可能认为i386部分会说,但它没有:@old_timer
extern long*A_Td不起作用(并且可能会可怕地崩溃),但是
外部长时间运行应该可以工作(假设C
long
与assembler
.long
大小相同)。正确的做法是在asm中需要一定程度的间接寻址。我在想可以直接使用函数标签或单个项……忘记地址存储。
extern a_Td
的隐式类型为
int
。真奇怪。您一定要使用
extern long A_Td[]
gcc hello1.o test_glob.c 
./a.out
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