【问题标题】:Compiling 32 bit Assembler on 64 bit ubuntu [duplicate]在 64 位 ubuntu 上编译 32 位汇编器 [重复]
【发布时间】:2012-10-22 02:59:23
【问题描述】:

我有用 32 位汇编语言编写的程序...现在我无法在 64 位操作系统上编译它。在我们学校,它们是特定的,程序必须以 32 位版本编写。这是我的程序:

bits 32
extern _printf
global _start

section .data
    message db "Hello world!!", 10, 0

section .text

_start:
    pushad 
    push dword message
    call _printf 
    add esp, 4 
    popad 
    ret

有什么想法吗?我已经尝试了很多方法来编译它。 编译后的错误输出:

nasm -f elf64 vaja4.asm
ld vaja4.o -o vaja4
./vaja4

输出:

vaja4.o: In function `_start':
vaja4.asm:(.text+0x7): undefined reference to `_printf'

【问题讨论】:

  • 不应该是 printf 而不是 _printf 吗?
  • 同样的错误:vaja4.o: In function start': vaja4.asm:(.text+0x7): undefined reference to printf'

标签: linux ubuntu assembly 64-bit 32-bit


【解决方案1】:

首先将_printf更改为printf,将_start符号更改为main,然后使用gcc链接目标文件,目标文件会自动链接到libc你需要这样做是因为 AFAIK 没有main 就无法链接到 libc。另外你应该在汇编时使用 elf32 而不是 elf64,因为代码有 32 位指令:

bits 32
extern printf
global main

section .data
    message db "Hello world!!", 10, 0

section .text

main:
    pushad 
    push dword message
    call printf 
    add esp, 4 
    popad 
    ret

并使用:

nasm -f elf32 vaja4.asm
gcc -m32 vaja4.o -o vaja4
$./test 
$Hello world!!

编辑:

由于您现在在 64 位系统上编译 32 位代码,因此您需要安装 32 位版本的库

apt-get install ia32-libs 

【讨论】:

  • 是的,这是正确的方法。如果您想使用 libc,您应该使用main 作为入口点并使用 gcc 进行链接,以便拉入正确的 libc 部分并处理初始化/关闭。此外,仅从 main 返回有效,如果您创建没有 libc 的二进制文件,则必须使用退出系统调用。
  • 好吧,我试过你的方法。在 gcc -m32 vaja4.o -o vaja4 之后,它给了我错误输出:pastebin.com/jX3N2GSJ
  • 你需要安装 32 位库 apt-get install ia32-libs
  • 我尝试安装该库,但仍然出现同样的错误。现在我安装了 libc6-dev-i386 库,它可以工作了!泰:)
  • 你可以从一个只定义_start的程序链接libc。但是,如果您制作静态二进制文件,则必须调用 glibc 的 init 函数,或者使用不需要 init 函数的 libc(如 musl)。 (Linux 上的动态链接在 _start 之前调用 glibc 的 init 函数)。请参阅我对我将其标记为副本的问题的回答。 (_printfprintf 的问题是分开的,但除此之外它问的是同一件事)
【解决方案2】:

在 Ubuntu 12.10 上,需要先安装开发包

​​>
sudo apt-get update
sudo apt-get install libc6-dev-i386

gcc -m32 vaja4.o -o vaja4

上班。

【讨论】:

    【解决方案3】:

    我怀疑您看到的错误是因为 32/64 位问题。您看到的错误,即

    vaja4.asm:(.text+0x7): undefined reference to `_printf'
    

    清楚地告诉你符号 _printf 是未定义的,这意味着 printf 函数的库没有被链接。

    您的链接步骤,即

    ld vaja4.o -o vaja4
    

    不包括任何库。您需要将程序与可以提供 printf 函数定义的库链接。我相信 ld 应该自己选择库而不用这些消息打扰你,但是因为它无法为这个函数找到合适的 C 库,我猜你没有所需的库,即缺少 32 位或 64 库。

    无论如何,请尝试以下命令序列来组装和链接您的程序:

    nasm -f elf vaja4.asm
    ld -m elf_i386 vaja4.o vaja4
    ./vaja4
    

    【讨论】:

    • 甚至ld -m elf_i386 -I/lib/ld-linux.so.2 -lc vaja4.o -o vaja4 可能不需要-I 开关 - 肯定需要输出文件名上的-lc-o_start 标签被跳转到,而不是被调用。所以你不能从中ret。更容易使用main 和 gcc...
    【解决方案4】:

    在我看来你忘记链接 C 库,这是提供 printf 函数(和其他)的部分:

    ld vaja4.o -o vaja4 -lc
    

    【讨论】:

      猜你喜欢
      • 2018-05-02
      • 1970-01-01
      • 2013-10-20
      • 1970-01-01
      • 2013-04-15
      • 2017-01-21
      • 2023-03-20
      相关资源
      最近更新 更多