mov指令
mov指令的作用是将源操作数S中的数据复制到目的操作数D中,mov指令有一个数据格式和两个操作数,因此一般的形式为[movx S D]。其中x为数据格式,S为源操作数,D为目的操作数。
这里举一个简单的例子,比如我们有一条指令为movl %edx %eax。那么它的执行过程就如下图所示。
可以看到,在指令执行之后,%edx寄存器当中的内容会被复制到%eax寄存器。需要一提的是,mov指令可以在后面加上任何数据格式,比如上面这一过程中,数据格式则为四个字节,也就是双字。因此不难推断出,我们还可以使用movb和movw去复制一个字节或者两个字节。
movs指令
movs指令的作用是将源操作数S中的数据做符号扩展后,再复制到目的操作数D中,movs指令有两个数据格式和两个操作数,因此一般的形式为[movsxy S D]。其中x、y为数据格式,S为源操作数,D为目的操作数。其中x、y的组合一共有三种,分别是bw、bl、wl,这三个组合代表的意思分别是单字节到双字节,单字节到双字以及双字节到双字。
这里LZ依然举一个例子,对于指令movswl %dx %eax来讲,它的作用如下图所示。
这里为了可以看出符号位的扩展,因此LZ这里使用了十六进制的整数表示方式。可以看到,movs指令将0x8FFF扩展以后存入%eax寄存器,其中%dx为寄存器%edx的后16位表示。
movz指令
movz指令的作用是将源操作数S做零扩展后,再复制到目的操作数中。它与movs指令十分相似,也有两个数据格式和两个操作数,因此一般的形式为[movzxy S D]。其中x、y为数据格式,S为源操作数,D为目的操作数。其中x、y的组合一共有三种,分别是bw、bl、wl,这三个组合代表的意思分别是单字节到双字节,单字节到双字以及双字节到双字。
这里依然采用相似的示例,我们来看看对于指令movzwl %dx %eax来讲,它的作用与上面的movs有何不同。
可以看出,movz与movs指令是十分相似的,只是这里扩展后,目标寄存器%eax的前16位为0而不再是1。
push指令
push指令与上面的mov族指令有着不同,它的目的操作数被固定为栈顶,因此它的指令当中没有目的操作数。另外有一点需要注意的是,它在进行复制操作之前,需要移动栈顶指针(-4)。push指令的一般形式为[pushl S],其中l代表数据格式为双字,S为源操作数,目的操作数默认为栈顶。
pop指令
pop指令与push指令是做的相反的操作,一个是入栈一个是出栈。对于pop指令来讲,它的源操作数被固定为栈顶,相反,它会先进行复制操作,然后再移动栈指针。pop指令的一般形式为[popl D],其中l代表数据格式为双字,D为目的操作数,源操作数默认为栈顶。
push指令:sub $4, %esp 然后move %ebp, (%esp),//先将地址减4,再将0x123放入
pop指令:move (%esp), %eax 然后 add $4, %esp//先拿出0x123,在将地址加4
x86 寄存器解释: http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html
转自:
作者:zuoxiaolong(左潇龙)