传送指令

简单的数据传送指令

指令 效果 全称 描述
MOV S,D D←S   传送
movb   move byte 传送字节
movw   move word 传送字
movl   move long word 传送双字
movq   move quadword 传送四字
movadsq I,R R←I move abs quadword 传送绝对的四字

※MOV指令只会更新目的操作数指定的那些寄存器字节或内存位置,但是movl指令以寄存器作为目的时,会把该寄存器高位4字节也设置为0.造成这个特殊性的原因时x86-64采用的惯例,即任何为寄存器生产32位值的指令都会把该寄存器的高位部分置0。

零扩展数据传送指令

指令 效果 全称 描述
MOVZ S,R R←零扩展(S)   以零扩展进行传送
movzbw   move zero extend byte to word 将做了零扩展的字节传送到字
movzbl   move zero extend byte to long word 将做了零扩展的字节传送到双字
movzwl   move zero extend word to long word 将做了零扩展的字传送到双字
movzbq   move zero extend byte to quadword 将做了零扩展的字节传送到四字
movzwq   move zero extend word to quadword 将做了零扩展的字传送到四字

我们发现这里没有movzlq,原因参考上一节※处movl的解释。同理当我们在c代码中把unsigned char或者unsigned short类型赋值给unsigned long应当使用movzbq或movzwq指令,但是生产的汇编代码却是movzbl或movzwl。

unsigned long btl(unsigned char b) {
	unsigned long result = b;
	return result;
}

unsigned long wtl(unsigned short b) {
	unsigned long result = b;
	return result;
}
btl:
    movzwl	%dil, %eax
    ret

wtl:
    movzwl	%di, %eax
    ret

符号扩展传送指令

指令 效果 全称 描述
MOVS S,R R←符号扩展(S)   传送符号扩展的字节
movsbw   move sign extend byte to word 将做了符号扩展的字节传送到字
movsbl   move sign extend byte to long word 将做了符号扩展的字节传送到双字
movswl   move sign extend word to long word 将做了符号扩展的字传送到双字
movsbq   move sign extend byte to long quadword 将做了符号扩展的字节传送到四字
movswq   move sign extend word to long quadword 将做了符号扩展的字传送到四字
movslq   move sign extend long word to long quadword 将做了符号扩展的双字传送到四字
cltq %rax←符号扩展(%eax) convert long word to quadword 把%eax符号扩展到%rax

压入和弹出栈指令

指令 效果 全称 描述 解释
pushq S R[%rsp]←R[%rsp]-8;
M[R[%rsp]]←S
push quadword 将四字压入栈 寄存器rsp的值-8,然后将S的值写入rsp寄存器指向的内存地址
popq D D←M[R[%rsp]];
R[%rsp]←R[%rsp]+8
pop quadword 将四字弹出栈 将rsp寄存之指向内存地址的值写入D,然后寄存器rsp的值+8

程序栈在程序启动后时固定大小的,我们可以看作一个桶一样,先进的数据会在栈底,内存地址值大,栈顶的值是最低的,所以push到栈时栈指针rsp寄存器的值需要-8.


IMAKIBA

Welcom to my blog!