我有两个源文件,一个在汇编中,一个在 c 中。该程序集包含对 c 源代码中的静态字符串的引用。我在程序集中定义了一个从 c 源代码调用的函数,它工作正常,没有任何问题。但是,当我尝试从程序集中调用 printf 并将 c 源文件中的字符串作为参数传递时,我得到了乱码输出或根本没有输出。
我使用nasm将程序集编译成elf32-i386,使用gcc编译c文件。幸运的是,我尝试过使用和不使用调试信息并得到相同的结果。
以下是简单的源文件:
电源:
SECTION .text
global s_func
extern c_str
extern printf
s_func:
sub esp, 4
mov dword [esp], c_str
call printf
add esp, 4
ret
主.c:
#include <stdio.h>
const char* c_str = "Sup.";
extern void s_func(void);
int main(void)
{
printf(c_str); //prints as expected
s_func(); //weird stuff
}
生成文件:
main : main.o main.s.o
gcc main.o main.s.o -o main
main.o :
gcc -g -c main.c -o main.o
main.s.o :
nasm -f elf main.s -o main.s.o
这是让我印象深刻的部分,如果你将这两个文件编译成对象然后将它们链接在一起,你会发现对 printf 的调用没有什么不同,无论是源代码。代码段相同,并且 c_str 在两个汇编列表中包含相同的地址。
在 main.c 中调用:
printf(c_str); //prints as expected
80483ed: a1 14 a0 04 08 mov 0x804a014,%eax
80483f2: 89 04 24 mov %eax,(%esp)
80483f5: e8 06 ff ff ff call 8048300 <printf@plt>
调用 main.s
08048410 <s_func>:
8048410: 83 ec 04 sub $0x4,%esp
8048413: b8 14 a0 04 08 mov $0x804a014,%eax
8048418: 89 04 24 mov %eax,(%esp)
804841b: e8 e0 fe ff ff call 8048300 <printf@plt>
8048420: 83 c4 04 add $0x4,%esp
8048423: c3 ret
也许我想保留一些寄存器?我已经在 s_func 上设置了一个正常的堆栈帧,但是它仍然失败。