x86 mov / add指令和内存寻址
x86 mov / add Instructions & Memory Addressing
我正在学习 class 中的 x86 汇编,我对如何区分寄存器操作数和内存引用的作用感到非常困惑。我有几个困惑,希望能澄清。
下面的代码是我教科书上说的分别做push和pop的long way:
subl , %esp
movl %ebp, (%esp)
movl (%esp), %eax
addl , %esp
那么在 subl 指令中,我们总能期望 %esp 保存一个地址值吗?
还有这两个movl函数有什么区别?第一个可以写成
吗
movl (%ebp), %esp
?对于第二个 movl,是移动 %esp 的地址还是移动 %esp 指向的值?
作为后续行动,为什么我们不能像这样让源和目标成为内存引用?
movw (%eax), 4(%esp)
最后,对于以下代码:
movb (%esp, %edx, 4), %dh
如果源超过 1 个字节(%dh 的大小),那么会发生什么?它只是截断值吗?
抱歉,问题太多了,我们将不胜感激。
The following code is what my textbook says is the long way to do push
and pop respectively:
subl , %esp
movl %ebp, (%esp)
movl (%esp), %eax
addl , %esp
So in the subl instruction, can we always expect %esp to hold an
address value?
是的。 ESP
寄存器保存最后一个压入堆栈的值的内存地址。
Also what is the difference between the two movl functions? Can the
first one be written as
movl (%ebp), %esp
? And for the second movl, does that move the address of %esp or does
it move the value pointed to by %esp?
MOV
指令在 AT&T
语法中需要两个操作数:源和目标。 MOV
将数据(在本例中为 32 位,由 L
后缀表示)从写入左侧的第一个操作数复制到写入右侧的第二个操作数。如果其中一个被括号括起来,则表示该操作数是一个内存操作数,括号中的值是它的内存地址,而不是实际值)
所以,movl %ebp,(%esp)
的意思是:将寄存器EBP
的值复制到内存中,在寄存器ESP
.
的值指向的地址
movl (%ebp),%esp
的意思是:从EBP
的值指向的内存地址开始复制32位数据到ESP
寄存器中。
所以你正在改变运动的方向。
As a follow-up then, why can't we have the source and destination be
memory references like so?
movw (%eax), 4(%esp)
简短回答:因为英特尔使用的编码不允许这样做。长答案:英特尔设计 ISA 的方式,可用资源计算老式 8086 中的两个有效地址等
And lastly, for the following code:
movb (%esp, %edx, 4), %dh
if the source is more than 1 byte (the size of %dh), then what
happens? Does it just truncate the value?
源与目标大小相同。这是由 B
后缀和目标是 8 位寄存器这一事实强加的。括号中的值就是单个内存字节的地址。对了,这个地址是ESP+EDX*4
So in the subl instruction, can we always expect %esp to hold an address value?
根据定义是的,因为下一条指令使用它作为地址。无论里面有什么垃圾,现在都有一个地址。如果它是像 0xDEADBEEF 这样的废话..那么现在就是一个地址。它可能是也可能不是有效地址(希望是有效的,无效的堆栈是一件坏事),但这是另一回事。
Also what is the difference between the two movl functions?
"push"中使用的写入内存,"pop"中使用的读取。右侧的括号表示它是写入,左侧的括号表示它是读取。那么你能把它们调过来吗?显然不是,它会做一些不同的事情。 movl (%ebp), %esp
将从内存中读取一些内容,然后更改堆栈所在的位置。
As a follow-up then, why can't we have the source and destination be memory references like so?
因为不能,所以没有这样的说明。它不适合正常的 operand encoding。我想这样的指令可能已经存在,但它不存在,所以你不能使用它。
movb (%esp, %edx, 4), %dh
if the source is more than 1 byte (the size of %dh), then what happens?
根据定义,指令不会读取 1 个字节。
我正在学习 class 中的 x86 汇编,我对如何区分寄存器操作数和内存引用的作用感到非常困惑。我有几个困惑,希望能澄清。
下面的代码是我教科书上说的分别做push和pop的long way:
subl , %esp
movl %ebp, (%esp)
movl (%esp), %eax
addl , %esp
那么在 subl 指令中,我们总能期望 %esp 保存一个地址值吗?
还有这两个movl函数有什么区别?第一个可以写成
吗movl (%ebp), %esp
?对于第二个 movl,是移动 %esp 的地址还是移动 %esp 指向的值?
作为后续行动,为什么我们不能像这样让源和目标成为内存引用?
movw (%eax), 4(%esp)
最后,对于以下代码:
movb (%esp, %edx, 4), %dh
如果源超过 1 个字节(%dh 的大小),那么会发生什么?它只是截断值吗?
抱歉,问题太多了,我们将不胜感激。
The following code is what my textbook says is the long way to do push and pop respectively:
subl , %esp movl %ebp, (%esp) movl (%esp), %eax addl , %esp
So in the subl instruction, can we always expect %esp to hold an address value?
是的。 ESP
寄存器保存最后一个压入堆栈的值的内存地址。
Also what is the difference between the two movl functions? Can the first one be written as
movl (%ebp), %esp
? And for the second movl, does that move the address of %esp or does it move the value pointed to by %esp?
MOV
指令在 AT&T
语法中需要两个操作数:源和目标。 MOV
将数据(在本例中为 32 位,由 L
后缀表示)从写入左侧的第一个操作数复制到写入右侧的第二个操作数。如果其中一个被括号括起来,则表示该操作数是一个内存操作数,括号中的值是它的内存地址,而不是实际值)
所以,movl %ebp,(%esp)
的意思是:将寄存器EBP
的值复制到内存中,在寄存器ESP
.
movl (%ebp),%esp
的意思是:从EBP
的值指向的内存地址开始复制32位数据到ESP
寄存器中。
所以你正在改变运动的方向。
As a follow-up then, why can't we have the source and destination be memory references like so?
movw (%eax), 4(%esp)
简短回答:因为英特尔使用的编码不允许这样做。长答案:英特尔设计 ISA 的方式,可用资源计算老式 8086 中的两个有效地址等
And lastly, for the following code:
movb (%esp, %edx, 4), %dh
if the source is more than 1 byte (the size of %dh), then what happens? Does it just truncate the value?
源与目标大小相同。这是由 B
后缀和目标是 8 位寄存器这一事实强加的。括号中的值就是单个内存字节的地址。对了,这个地址是ESP+EDX*4
So in the subl instruction, can we always expect %esp to hold an address value?
根据定义是的,因为下一条指令使用它作为地址。无论里面有什么垃圾,现在都有一个地址。如果它是像 0xDEADBEEF 这样的废话..那么现在就是一个地址。它可能是也可能不是有效地址(希望是有效的,无效的堆栈是一件坏事),但这是另一回事。
Also what is the difference between the two movl functions?
"push"中使用的写入内存,"pop"中使用的读取。右侧的括号表示它是写入,左侧的括号表示它是读取。那么你能把它们调过来吗?显然不是,它会做一些不同的事情。 movl (%ebp), %esp
将从内存中读取一些内容,然后更改堆栈所在的位置。
As a follow-up then, why can't we have the source and destination be memory references like so?
因为不能,所以没有这样的说明。它不适合正常的 operand encoding。我想这样的指令可能已经存在,但它不存在,所以你不能使用它。
movb (%esp, %edx, 4), %dh
if the source is more than 1 byte (the size of %dh), then what happens?
根据定义,指令不会读取 1 个字节。