汇编中寻址模式之前的减号是啥意思,例如 -0x2(%rbx)

Posted

技术标签:

【中文标题】汇编中寻址模式之前的减号是啥意思,例如 -0x2(%rbx)【英文标题】:What does a minus before an addressing mode mean in assembly, like -0x2(%rbx)汇编中寻址模式之前的减号是什么意思,例如 -0x2(%rbx) 【发布时间】:2020-12-24 16:20:27 【问题描述】:
                    201036:    push   %rbp
                    201037:    push   %rbx
                    201038:    sub    $0x28,%rsp
                    20103c:    mov    %rsp,%rsi
                    20103f:    callq  2014a5 <read_input>
                    201044:    cmpl   $0x0,(%rsp)
                    201048:    jne    201051 <func_2+0x1b>
                    20104a:    cmpl   $0x1,0x4(%rsp)
                    20104f:    je     201056 <func_2+0x20>
                    201051:    callq  20146f <wrong_input>
                    201056:    mov    %rsp,%rbp
                    201059:    lea    0x4(%rsp),%rbx
                    20105e:    add    $0x18,%rbp
                    201062:    mov    -0x2(%rbx),%eax
                    201065:    add    -0x4(%rbx),%eax
                    201068:    cmp    %eax,(%rbx)
                    20106a:    je     201071 <func_2+0x3b>
                    20106c:    callq  20146f <wrong_input>
                    201071:    add    $0x2,%rbx
                    201075:    cmp    %rbp,%rbx
                    201078:    jne    201062 <func_2+0x2c>
                    20107a:    add    $0x28,%rsp
                    20107e:    pop    %rbx
                    20107f:    pop    %rbp
                    201080:    retq  

好吧,如果我把它分成几行:

mov    %rsp,%rbp : puts value of rsp into rbp
lea    0x4(%rsp),%rbx : put "0x4*rsp" into rbx. (*rsp = address of or rsp)
add    $0x15,%rbp : adds the integer that at "0x15" to rbp and saves the sum in 
                                                              rbp.

mov    -0x2(%rbx),%eax : moves the value that inside of ??? to eax
add    -0x4(%rbx),%eax : adds the value that inside of ??? to eax as saves the sum 
                                                                           in eax.

cmp    %eax,(%rbx): compares eax with rbx.

好吧,我真的不明白“0x4(%rsp)”是什么意思,“-0x2(%rbx)”和“-0x4(%rbx)”中的减号是什么意思..

我正在尝试将这些点连接起来。这似乎是一个循环,增加 rbx 或 eax 然后比较它们。虽然我不太明白。

【问题讨论】:

related: A couple of questions about [base + index*scale + disp] / How does "mov (%ebx,%eax,4),%eax" work? / Using LEA on values that aren't addresses / pointers? 描述了使用 LEA 进行简单数学运算。 【参考方案1】:

...我不太明白“0x4(%rsp)”是什么意思,“-0x2(%rbx)”和“-0x4(%rbx)”中的减号是什么意思..

这些数字要加到括号之间的数值上,这个数字就是位移分量。

0x4(%rsp)中,真实地址变为%RSP寄存器中的值 4. 在-0x2(%rbx) 中,真实地址变为%RBX 寄存器中的值 2。

例如如果在mov -0x2(%rbx),%eax%RBX 寄存器保存100002,那么%EAX 寄存器接收存储在内存地址100000 的双字。

例如如果在lea 0x4(%rsp),%ebx%RSP 寄存器保存100000,那么%EBX 寄存器接收值100004。


[代码已添加]

现在您已经添加了更多代码,我们可以尝试弄清楚循环是如何工作的。

           mov    %rsp,%rsi
           callq  2014a5 <read_input>
           cmpl   $0x0,(%rsp)
           jne    201051 <func_2+0x1b>
           cmpl   $0x1,0x4(%rsp)
           je     201056 <func_2+0x20>
201051:    callq  20146f <wrong_input>

201056:    mov    %rsp,%rbp
           lea    0x4(%rsp),%rbx
           add    $0x18,%rbp

201062:    mov    -0x2(%rbx),%eax
           add    -0x4(%rbx),%eax
           cmp    %eax,(%rbx)
           je     201071 <func_2+0x3b>
           callq  20146f <wrong_input>
201071:    add    $0x2,%rbx
           cmp    %rbp,%rbx
           jne    201062 <func_2+0x2c>

(-) 无法解决

为了避免第一个 callqwrong_input(%rsp) 的前 8 个字节需要是:

%rsp        %rbx
v           v
00,00,00,00,01,00,00,00
      -----------
+++++++++++ ===========

但是循环的第一次迭代会失败,然后第二次callq wrong_input 因为:

-----------    mov -0x2(%rbx),%eax    --> 0x00010000
+++++++++++    add -0x4(%rbx),%eax    --> 0x00010000 + 0x00000000
===========    cmp %eax,(%rbx)        --> 0x00010000 <> 0x00000001

(+) 思考斐波那契

如果我们只考虑循环部分,那么我们可以找到一个可以通过的整数序列。他们在这里:

65536, 131073, 327683, 851976, 2228245, 5832759, 144

存入内存时需要查看:

            first                                                 last
%rsp        %rbx                     -->                          %rbx  %rbp
v           v                                                     v     v
00,00,01,00,01,00,02,00,03,00,05,00,08,00,0D,00,15,00,22,00,37,00,59,00,90,00
      -----------                                           -----------
+++++++++++ ===========                               +++++++++++ ===========

请注意,循环在%rbp 中读取超出末尾的一个单词,因此输入实际上是六个半双字整数!

【讨论】:

@NoobCoder 因为它是一条LEA 指令,所以它是存储在%RBX 寄存器中的地址本身。不涉及从内存加载!如果 %RSP 是 0x2020,那么 %RBX 只接收值 0x2024。 “真地址变值”是什么意思?我真的不明白“lea 0x4(%rsp),%rbx”是做什么的。它会去 RSP 的地址,加 4,然后去新地址,并在 RBX 中获取它的值吗?还是它实际上将地址(例如 RBX 内的“0x0120”)作为值? 是的,我知道这是 LEA 的目的。但是mov呢?正如您在示例中提到的那样。它会移动地址内的值吗? @NoobCoder 使用括号的指令是指某个内存位置。一旦将所有地址组件放在一起,我们就有了真实地址。然后指令接管。如果是LEA,我们只使用地址的值,如果是MOV,我们从内存中读取或写入内容。 @NoobCoder 您的代码 sn-p 没有循环!为此,您需要某种跳转指令,很可能是CMP 指令下方的条件跳转。

以上是关于汇编中寻址模式之前的减号是啥意思,例如 -0x2(%rbx)的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言中的DEC是啥意思?

泄漏仪器中的减号是啥意思?

你好,shell脚本中,使用两个减号,两边没有单词。这个是啥意思?是控制运行参数吗

x86---32汇编---内存寻址模式

win 10系统32位,64位是啥意思?请简单点说

bytes是啥意思