我有两个源文件,一个在汇编中,一个在c中。程序集包含对c源中的静态字符串的引用。我在从c源调用的程序集中定义了一个函数,它工作正常,没有任何障碍。但是当我尝试从程序集中调用printf并从c源文件中传递一个字符串作为参数时,我得到输出乱码或者根本没有输出。
我使用nasm将程序集编译成elf32-i386,使用gcc编译c文件。无论调试信息有没有尝试过,我都尝试了相同的结果,幸运的是。
以下是简单的源文件:
main.s:
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
main.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上设置了一个正常的堆栈帧,但是它仍然失败。
答案 0 :(得分:0)
我认为链接目标文件时存在问题(由于在程序集中使用了print)。
我认为最好的方法是创建一个包含使用c库的printf的函数的GAS程序集,然后使用“as”命令来汇编文件。
然后使用gcc编译器编译c代码,并使用以下命令将GAS创建的目标文件链接到一行。
如果GAS创建的对象文件是main_s.o,
gcc main_c.c main_s.o -o main
所以gcc首先创建main_c.c的对象格式,然后链接main_c.o和main_s.o,它将给出当前链接的elf文件。