【问题标题】:Linked assembly subroutine doesn't work as expected链接的汇编子例程无法按预期工作
【发布时间】:2013-04-21 06:26:23
【问题描述】:

我正在 FASM 中编写一个简单的子程序来将 32 位无符号整数打印到 STDOUT。这是我想出的:

format elf
public uprint

section ".text" executable
uprint:
    push ebx
    push ecx
    push edx
    push esi
    mov  ebx, 10
    mov  ecx, buf + 11
    xor  esi, esi
do:
    dec ecx
    xor edx, edx
    div ebx
    add dl, 0x30
    mov [ecx], dl
    inc esi
    test eax, 0
    jnz do
    mov eax, 4
    mov ebx, 1
    mov edx, esi
    int 0x80
    pop esi
    pop edx
    pop ecx
    pop ebx
    ret

section ".data" writeable
    buf rb 11

然后我又写了一个程序来测试上面的子程序是否正常工作:

format elf
extrn uprint
public _start

section ".text" executable
_start:
    mov eax, 1337
    call uprint
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80
    mov eax, 1
    xor ebx, ebx
    int 0x80

section ".data"
    newline db 0x0A

我将这两个程序编译成它们对应的目标文件,并将它们链接起来以创建可执行文件。

在执行程序时,它只显示7 而不是1337。事实证明,无论数字本身如何,都只显示数字的最后一位。

这很奇怪,因为我的uprint 子程序是正确的。事实上,如果我将这两个程序组合成一个程序,那么它会正确显示1337

我做错了什么?

【问题讨论】:

  • 你能在调试器中运行它,看看uprint开头的eax是什么内容吗?
  • @Mellowcandle - 我不知道如何调试 FASM 程序。是否可以将 GDB 与 FASM 一起使用?
  • AFAIK 使用 GDB 是不可能的

标签: linux assembly ld system-calls fasm


【解决方案1】:

我得到一个明显的印象,即您的 LINK 操作是在 _start 之前构建 uprint,而您实际上是在输入 UPRINT,而不是像您期望的那样在 _start

【讨论】:

    【解决方案2】:

    我发现了我的错误。我正在使用test eax, 0,它总是设置零标志。因此只处理第一个数字。我需要使用test eax, eaxcmp eax, 0

    【讨论】:

    • 我不相信。如果您在将两者组合成一个模块时对uprint 使用完全相同的例程,因为test eax, 0 总是设置零标志,jnz do 在处理第一个数字后会发现Z 设置,所以它应该从来没有产生过1337——但你说它有过。这里没有加起来......
    • @PeterWright - 确实。我不记得我第一次做了什么,但我相信我使用了cmp eax, 0(这就是它起作用的原因)。然后,当我创建一个单独的测试程序时,我将cmp 更改为test 以节省计算机周期。 -_-
    猜你喜欢
    • 1970-01-01
    • 2019-06-20
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多