在 linux 中无法从 C 访问程序集的正确全局标签数据
Unable to access correct global label data of assembly from C in linux
我有一个汇编代码 (hello1.s),其中定义了全局标签 A_Td,我想访问用 global 定义的所有长数据值label A_Td from/inside C程序.
.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
由于A_Td定义在text段,所以放在code段,只加载一份到内存
使用 yasm ,我生成了 hello1.o 文件
yasm -p gas -f elf32 hello1.s
现在,为了使用全局标签 A_Td 访问所有长数据,我编写了以下 C 代码 (test_glob.c) 从这里获取线索 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;
}
使用以下命令我编译了 C 程序,然后 运行 C 代码。
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
C 程序只能正确访问前 4 个 long 值。为什么会这样?
C 程序内部需要做什么才能正确访问其余数据?
我正在使用 Linux。解决此问题或任何 link 的任何帮助都将是一个很大的帮助。提前致谢。
"long"在这个系统中有多少字节?
在我看来,printf 将数字解释为四字节有符号整数,其中值 3282310938
具有十六进制值 C3A4171A
,高于 7FFFFFFF
(十进制: 2147483647) 这是最大的四字节正符号数,因此是负值 -1012656358
。
我假设汇编器只是将这四个字节数解释为无符号数。
如果您使用 %lu
而不是 %ld
,printf 会将数字解释为无符号,并且应该显示您所期望的。
我有一个汇编代码 (hello1.s),其中定义了全局标签 A_Td,我想访问用 global 定义的所有长数据值label A_Td from/inside C程序.
.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
由于A_Td定义在text段,所以放在code段,只加载一份到内存
使用 yasm ,我生成了 hello1.o 文件
yasm -p gas -f elf32 hello1.s
现在,为了使用全局标签 A_Td 访问所有长数据,我编写了以下 C 代码 (test_glob.c) 从这里获取线索 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;
}
使用以下命令我编译了 C 程序,然后 运行 C 代码。
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
C 程序只能正确访问前 4 个 long 值。为什么会这样?
C 程序内部需要做什么才能正确访问其余数据?
我正在使用 Linux。解决此问题或任何 link 的任何帮助都将是一个很大的帮助。提前致谢。
"long"在这个系统中有多少字节?
在我看来,printf 将数字解释为四字节有符号整数,其中值 3282310938
具有十六进制值 C3A4171A
,高于 7FFFFFFF
(十进制: 2147483647) 这是最大的四字节正符号数,因此是负值 -1012656358
。
我假设汇编器只是将这四个字节数解释为无符号数。
如果您使用 %lu
而不是 %ld
,printf 会将数字解释为无符号,并且应该显示您所期望的。