【问题标题】:mov -0x10(%rbp), %r10 does not set %r10 to correct value?mov -0x10(%rbp), %r10 没有将 %r10 设置为正确的值?
【发布时间】:2021-03-04 15:02:17
【问题描述】:

我正在编写一个代码生成问题,其中输出是 x86/64 汇编代码文件。我有以下输出序列

mov -0x8(%rbp), %r10     // r10 = 0 at the moment
mov $0xa, %r11           // r11 = 10
cmp %r11, %r10       
setg -0x10(%rbp)         // -0x10(%rbp) = 0
mov -0x10(%rbp), %r10    // %r10 is desired to be 0, but here is the problem

根据调试器,r10 设置为r10 0x100000000 4294967296

我不明白为什么 %r10 的内容没有设置为期望值0

有什么我错过的约定吗?

整个生成的 x86/64 程序是

    .text
    .globl  _f1
_f1:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    jmp f1.start
    .text
f1.start:
    movq    -8(%rbp), %r10
    movq    $10, %r11
    cmpq    %r11, %r10
    setg    -16(%rbp)
    movq    -16(%rbp), %r10
    cmpq    $1, %r10
    je  f1.then
    jmp f1.end
    .text
f1.then:
    movq    $1, %rax
    movq    %rbp, %rsp
    popq    %rbp
    retq    
    .text
f1.end:
    movq    $0, %rax
    movq    %rbp, %rsp
    popq    %rbp
    retq    
    .text
    .globl  _f2
_f2:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    jmp f2.start
    .text
f2.start:
    movq    -8(%rbp), %r10
    movq    $10, %r11
    cmpq    %r11, %r10
    setg    -16(%rbp)
    movq    -16(%rbp), %r10
    cmpq    $1, %r10
    je  f2.then
    jmp f2.end
    .text
f2.then:
    movq    $1, %rax
    movq    %rbp, %rsp
    popq    %rbp
    retq    
    .text
f2.end:
    movq    $0, %rax
    movq    %rbp, %rsp
    popq    %rbp
    retq    
    .text
    .globl  _main
_main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $40, %rsp
    movq    $0, %rdi
    callq   _f1
    movq    %rax, -24(%rbp)
    movq    $15, %rdi
    callq   _f2
    movq    %rax, -32(%rbp)
    movq    -24(%rbp), %r10
    movq    -32(%rbp), %r11
    addq    %r10, %r11
    movq    %r11, -40(%rbp)
    movq    -40(%rbp), %rax
    movq    %rbp, %rsp
    popq    %rbp
    retq    

您可以将其保存到test.s,并通过运行以下命令生成可执行文件 clang -Wno-override-module -O1 -Wall -fno-asynchronous-unwind-tables -mstackrealign -o test test.s

【问题讨论】:

  • setg 设置单个字节。但是,您继续阅读整个 qword。你确定这是正确的吗?
  • 为什么要在这里费心记忆呢? setg %r10b 设置 R10 的低字节。最好在比较之前用xor %r10d, %r10d 将完整的R10 归零之后。或者之后使用movzbl %r10b, %r10d 将零扩展到完整的注册,尽管更糟糕的是especially within the same register defeating mov-elimination。您可以使用即时比较,例如 cmpq $0xa, -0x8(%rbp)
  • 无论如何,您的问题标题并没有反映问题。如果您使用调试器单步执行代码,您会看到 setg 仅写入 1 个字节,根据手册 felixcloutier.com/x86/setcc。这是一个非常糟糕/不方便设计的指令指令,不幸的是 AMD64 没有修复。

标签: assembly compiler-construction x86-64 codegen


【解决方案1】:

在cmets中回答,但只是为了给它一个完整的答案:

setcc 条件设置指令,相当不方便,只设置一个字节。所以setg -16(%rbp) 将字节设置为-16(%rbp),然后movq -16(%rbp), %r10 加载四字,其低字节是设置的结果,其高7 字节是之前发生在字节-15(%rbp)..-9(%rbp) 中的任何垃圾。

因此,您需要生成代码,要么在集合之前将整个四字显式归零,要么忽略所有其他字节(例如,将 movq -16(%rbp), %r10 替换为 movzbl -16(%rbp), %r10d),或者以其他方式处理问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 2014-01-13
    • 2012-05-15
    相关资源
    最近更新 更多