【问题标题】:Conditional jump not taken没有进行条件跳转
【发布时间】:2017-09-02 14:26:03
【问题描述】:

我从汇编(x86,linux)开始,只是为了好玩。这是我的第一个小程序,它只检查我是否通过命令行传递了一个参数,如果没有,它会打印一条消息,然后退出:

section .text
    global  _start

_start: 
    pop ebx     ;argc
    dec ebx
    test    ebx,1
    jne print_string
exit:
    mov ebx,0
    mov eax,0
    int 0x80

print_string:
    mov edx,len
    mov ecx,msg
    mov ebx,1
    mov eax,4
    int 0x80
    call    exit

section .data
msg db  "Ok, no arg was passed",0xa
len equ $ - msg

上面的代码有两个问题:

  1. jne 未被占用。我用gdb检查了ebxdec之后等于0x00,但是test指令没有改变EFLAGS。
  2. exit 系统调用没有退出!因此,我没有退出,而是在无限循环中打印了我的消息,因为 print_string 正在调用 exit 并且在 exit 之后有 print_string 一遍又一遍。

这里发生了什么?也欢迎任何其他关于代码的建议。谢谢。

【问题讨论】:

  • test 不会按照你的想法去做。你想要一个cmp。另外,你想要je 而不是jneexit 的系统调用号是 1 而不是 0。
  • 好的,这行得通。似乎我需要阅读更好的资料。如果您有兴趣发布任何关于跳转和 cmp 参考的答案,我很乐意将其标记为正确...
  • 通常谷歌搜索像“x86指令测试”会导致指令参考指南的HTML版本之一,像http://x86.renejeschke.de/和类似的。有时它们包含微小的不准确之处,但通常它们是检查(与调试器一起)如果某些东西没有按预期工作的第一件事。只有当调试器证明那些缩短的版本是错误的时,才需要深入研究英特尔官方文档(英特尔网站上免费提供的 pdf),或交叉检查几个快速参考。对于在 ASM 中进行编程,必须同时使用:调试器 + 文档

标签: linux assembly x86


【解决方案1】:

test 指令按位执行and,而不更改寄存器操作数。
test ebx,1 执行:flags = (ebx and 1)。或ZF = IsEven(ebx)

如果要测试 ebx = 1 是否需要使用 cmp
cmp 在不更改寄存器操作数的情况下执行减法。

cmp ebx,1 执行 flags = ebx - 1ZF = (ebx = 1)

系统调用退出
您为exit() 设置了错误的参数。

正确的代码是:

exit:
    mov ebx,0
    mov eax,1    <<-- 
    int 0x80

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 2021-10-20
    • 2015-08-04
    相关资源
    最近更新 更多