程序集源无法正确传递参数

时间:2012-04-22 16:47:53

标签: gcc assembly nasm

我有两个源文件,一个在汇编中,一个在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上设置了一个正常的堆栈帧,但是它仍然失败。

1 个答案:

答案 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文件。