为啥 JL 命令在我的汇编代码中不起作用?

Posted

技术标签:

【中文标题】为啥 JL 命令在我的汇编代码中不起作用?【英文标题】:why JL command doesn't work in my Assembly code?为什么 JL 命令在我的汇编代码中不起作用? 【发布时间】:2021-05-24 01:23:24 【问题描述】:

在我的汇编程序中,我很想知道 %rsp 得到的最小值(随着它的增长)与其初始值相比是多少,所以我在 main 中写道:

mov %rsp, %rcx #start
mov %rsp, %rdx #max

在推送之前我代码的每个部分(或任何其他可能影响 %rsp 的命令)我写道:

cmp %rsp, %rdx
jl next3 # current rsp is less that prev_max then skip the update of value for max
mov %rsp, %rdx
next3: # every time this is copied I change the number like next4, next5 etc...

但是当我调试我的代码时,rdx 和 rcx 共享相同的值,这是为什么呢?

【问题讨论】:

堆栈向下增长并且 at&t 使用反向操作数顺序。您要么想要cmp %rdx, %rsp,要么将jl 换成jg(或ja,因为您确实应该使用无符号)。 @Jester 也试过 ja,同样的问题你可以试试:onlinegdb.com/5CKsK1GNT 请注意,jgjamov 指令上更容易理解为 cmovna %rsp, %rdxcmovb %rsp, %rdx 嗯,实际上是我的错误,您确实有jl 跳过该块,这样应该可以工作。事实上,如果我将链接中的第 60 行更改为 jl,然后在第 186 行检查 rcxrdx,它们确实会有所不同。 是的,建议使用jb,因为它是无符号的,但jl 在一般情况下的效果与x86-64 中的堆栈位于正半部分一样好。 at&t 仍然使用相反的顺序,所以在 cmp %rsp, %rdx jl 跳转之后,如果 rdx < rsp 这是你想要的,因为这意味着 rdx 已经较低,所以你想跳过分配,因为堆栈增长了。 【参考方案1】:

您的堆栈检查代码实际上是正确的。由于您提供了完整的代码[*],我们可以看到从第 73 行开始存在问题:

    cmp (%rdi), %esi
    
    cmp %rsp, %rdx
    jl next4
    mov %rsp, %rdx
    next4:
    
    jne continue

您的堆栈检查位于cmp (%rdi), %esijne continue 之间,因此它将使用cmp %rsp, %rdx 中的标志。碰巧那些在那个时候是相等的,所以你的函数不会去continue而是返回。使用的堆栈空间只有 16 个字节。请注意,此堆栈检查块是无用的,因为堆栈指针不能从前一个更改,因此您可以删除第 74-80 行。然后,这将产生 0x40 字节的堆栈使用量,如您所料。

关于操作数顺序的问题,at&t 与 intel 正好相反。考虑这段代码:

mov $1, %eax
mov $2, %edx
cmp %eax, %edx
jl next

这将不会跳跃。


[*] https://onlinegdb.com/5CKsK1GNT 和 ja 改回 jl

【讨论】:

以上是关于为啥 JL 命令在我的汇编代码中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 simpledialog2 在我的 jQuery Mobile 代码段中不起作用?

为啥 button.click() 在我的脚本中不起作用?

模态在我的网络服务器中不起作用,但在 localhost 中起作用。这是为啥?

为啥使用命名空间在我的 C++ 项目中不起作用?

为啥 jQuery 在我的 rails 5 应用程序中不起作用?

为啥 MPI_SEND 在我的 for 循环中不起作用?如果明确说明它工作正常