【问题标题】:mixing c and assembly. On the terminal nothing printed混合 c 和组装。在终端上没有打印
【发布时间】:2014-05-04 08:57:09
【问题描述】:

我这里写的是一个简单的代码:

 printf.asm

 [EXTERN main]
 section .text
 global _start     
 _start:
       call main
       add esp, 8
       mov eax, 1
       xor ebx, ebx
       int 80h

和main.c

#include <stdio.h>

 int main()
 {
     char* str = "print from C :\\)";
     printf("%s", str);
 }

我这样编译代码:

nasm -g -f elf printf.asm -o printf.o

gcc -c -o main.o main.c

ld -o printf printf.o main.o -lc -I/lib/ld-linux.so.2

然后运行:

./printf

在终端上没有打印任何内容。为什么?

当我使用以下命令链接 ld -Ttext 0x1000 -o printf printf.o main.o -lc -I/lib/ld-linux.so.2 时,它会显示“Killed”字符串。如何解决这个问题?

成功获取的代码刚刚在 printf 函数中添加了一个换行符:printf("%s\n", str);。谢谢大家,问题解决了。

【问题讨论】:

  • 您是否尝试在 main() 开头放置断点并使用调试器查看是否到达那里?

标签: c assembly compilation linker nasm


【解决方案1】:

您试图在未先执行 C 启动代码的情况下调用 main()。你不应该那样做。基本上,C 启动会在跳转到 main() 之前初始化堆栈和变量存储。

您可以从 main() 调用汇编语言代码,因为这允许启动首先做它的事情。

【讨论】:

    【解决方案2】:

    您正在编写 _start 自己,这是一个 libc 启动函数。这就是您无法正确链接代码的原因。您也不应该触摸 _start 否则会破坏 libc。 要在 main 之前运行代码,您可以使用 ''attribute ((constructor))'' (它是 gcc 功能,在其他编译器中不可用)。

    【讨论】:

    • 这段代码正常编译运行,没有错误。你想说,如果我改写_starta f.e.一个代码会起作用吗?因此,也尝试不像以前那样在屏幕上打印任何内容。
    • 如果你不需要在 main 之前运行它,是的,它会工作,但如果你需要在 main 之前运行它,你应该使用 'attribute ((constructor))'。
    • 代码成功获取刚刚在printf函数中添加了换行符:printf("%s\n", str);
    【解决方案3】:

    带有 NASM 入口点的混合源以这种方式工作(在我的 64 位 Linux 上是 32 位):

    printf.asm:

    global _start
    extern main
    extern fflush
    
    section .text
     _start:
        call main
    
        push 0                      ; fflush (stdout)
        call fflush
        add esp, 4
    
        mov ebx,0                   ; exit code, 0=normal
        mov eax,1                   ; exit command to kernel
        int 0x80                    ; interrupt 80 hex, call kernel
    

    ma​​in.c

    #include <stdio.h>
    
    extern int main (void)
    {
        char* str = "print from C :\\)\n";
        printf("%s", str);
        return 0;
    }
    

    构建:

    nasm -felf32 -oprintf.o printf.asm
    gcc -c -m32 -omain.o main.c
    ld -I/lib32/ld-linux.so.2 -lc -m elf_i386 -o printf printf.o main.o
    

    我猜你可以管理 32 位 Linux 的更改 :-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      • 2018-03-15
      • 1970-01-01
      • 2021-01-12
      • 2020-12-17
      • 2023-01-16
      相关资源
      最近更新 更多