无法在linux中从C访问程序集的正确全局标签数据
我有一个汇编代码(hello1.s),其中定义了全局标签A_Td,我想从C程序中/从C程序中访问使用全局标签A_Td定义的所有长数据值无法在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
.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位,即使Clong
为64位。你在这里很幸运,但你需要阅读你的汇编程序手册。e、 g.说它是.int
的同义词,大小和字节顺序取决于目标.quad
是8个字节。嗯,我真的找不到它是否说x86的.long
是4字节。你可能认为i386部分会说,但它没有:@old_timerextern long*A_Td代码>不起作用(并且可能会可怕地崩溃),但是外部长时间运行代码>应该可以工作(假设Clong
与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