寻址模式前的减号在汇编中意味着什么,比如 -0x2(%rbx)
What does a minus before an addressing mode mean in assembly, like -0x2(%rbx)
201036: push %rbp
201037: push %rbx
201038: sub [=10=]x28,%rsp
20103c: mov %rsp,%rsi
20103f: callq 2014a5 <read_input>
201044: cmpl [=10=]x0,(%rsp)
201048: jne 201051 <func_2+0x1b>
20104a: cmpl [=10=]x1,0x4(%rsp)
20104f: je 201056 <func_2+0x20>
201051: callq 20146f <wrong_input>
201056: mov %rsp,%rbp
201059: lea 0x4(%rsp),%rbx
20105e: add [=10=]x18,%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 [=10=]x2,%rbx
201075: cmp %rbp,%rbx
201078: jne 201062 <func_2+0x2c>
20107a: add [=10=]x28,%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 [=11=]x15,%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 然后比较它们。不过我真的不明白。
... I can't really understand what "0x4(%rsp)" means, what the minus in "-0x2(%rbx)" and "-0x4(%rbx)" means..
这些数字是要加到括号之间的值,数字是位移分量。
在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 [=10=]x0,(%rsp)
jne 201051 <func_2+0x1b>
cmpl [=10=]x1,0x4(%rsp)
je 201056 <func_2+0x20>
201051: callq 20146f <wrong_input>
201056: mov %rsp,%rbp
lea 0x4(%rsp),%rbx
add [=10=]x18,%rbp
201062: mov -0x2(%rbx),%eax
add -0x4(%rbx),%eax
cmp %eax,(%rbx)
je 201071 <func_2+0x3b>
callq 20146f <wrong_input>
201071: add [=10=]x2,%rbx
cmp %rbp,%rbx
jne 201062 <func_2+0x2c>
(-)无解
为了避免第一个callq
到wrong_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
中读取了超出末尾的一个字,因此输入实际上是 六个半 双字整数!
201036: push %rbp
201037: push %rbx
201038: sub [=10=]x28,%rsp
20103c: mov %rsp,%rsi
20103f: callq 2014a5 <read_input>
201044: cmpl [=10=]x0,(%rsp)
201048: jne 201051 <func_2+0x1b>
20104a: cmpl [=10=]x1,0x4(%rsp)
20104f: je 201056 <func_2+0x20>
201051: callq 20146f <wrong_input>
201056: mov %rsp,%rbp
201059: lea 0x4(%rsp),%rbx
20105e: add [=10=]x18,%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 [=10=]x2,%rbx
201075: cmp %rbp,%rbx
201078: jne 201062 <func_2+0x2c>
20107a: add [=10=]x28,%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 [=11=]x15,%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 然后比较它们。不过我真的不明白。
... I can't really understand what "0x4(%rsp)" means, what the minus in "-0x2(%rbx)" and "-0x4(%rbx)" means..
这些数字是要加到括号之间的值,数字是位移分量。
在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 [=10=]x0,(%rsp)
jne 201051 <func_2+0x1b>
cmpl [=10=]x1,0x4(%rsp)
je 201056 <func_2+0x20>
201051: callq 20146f <wrong_input>
201056: mov %rsp,%rbp
lea 0x4(%rsp),%rbx
add [=10=]x18,%rbp
201062: mov -0x2(%rbx),%eax
add -0x4(%rbx),%eax
cmp %eax,(%rbx)
je 201071 <func_2+0x3b>
callq 20146f <wrong_input>
201071: add [=10=]x2,%rbx
cmp %rbp,%rbx
jne 201062 <func_2+0x2c>
(-)无解
为了避免第一个callq
到wrong_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
中读取了超出末尾的一个字,因此输入实际上是 六个半 双字整数!