csapp-chapter3--mov指令

数据传送mov

汇编mov精要

文章目录

  • 数据传送`mov`
    • ` 汇编mov精要`
  • mov的后缀
  • 操作数指示符
  • `movq`与`movabsq`
  • `MOVZ`和`MOVS`


mov的后缀

mov指令根据操作的数据size不同,具有不同的后缀指示

  • movb(传送字节)
  • movw(传送字)
  • movl(传送双字)
  • movq(传送四字)
C声明 Intel数据类型 汇编代码后缀 大小(byte)
char 字节 b 1
short w 2
int 双字 l 4
long 四字 q 8
char* 四字 q 8
float 单精度 s 4
double 双精度 l 8

注:后缀l代表传送双字,因为32bit被看作是长字(long-word)。但是汇编中也使用l代表4字节整数8字节双精度浮点数。大家可能会疑惑,那机器如何区分后缀为l时,表示的是上述的那种情况呢?事实上,当操作对象为浮点数的时候,使用的是一组完全不同的指令和寄存器,所以不会产生二义性。

操作数指示符

imm(rb,ri,s)
事实上上面的表示方式是最通用的,可以达到触类旁通的效果
这个表示形式会被计算为
I m m + R [ r b ] + R [ r i ] ∗ s Imm+R[r_b]+R[r_i]*s Imm+R[rb]+R[ri]s

可以理解为

  • Imm:偏移量,是个立即数
  • rb:基址寄存器
  • ri:变址寄存器
  • s:比例因子

movqmovabsq

movabsq传送绝对的四字,以任意的64bit立即数为原操作数,且只能以寄存器为目的
movq常规情况下只能以32bit补码数字的立即数为源操作数,然后符号扩展为64bit,放到目的。

MOVZMOVS

当把size较小的源值复制到较大的目的时使用,且源来自主存或寄存器,目的只能是寄存器。
且只有在movz和movs中,后面的指示数据size的后缀才能写两位


movz把目的中剩余字节填充为0

指令 效果 描述
MOV S ,R R<-零扩展(S) 以0扩展进行传送
movzbw 字节0扩展传送到字
movzbl 字节0扩展传送到双字
movzbq 字节0扩展传送到四字
movzwl 字0扩展传送到双字
movzwq 字0扩展传送到四字

目的的size一定是要大于源的


指令 效果 描述
MOV S, R R<-符号扩展(S) 以符号扩展进行传送
movsbw 字节符号扩展传送到字
movsbl 字节符号扩展传送到双字
movsbq 字节符号扩展传送到四字
movswl 字符号扩展传送到双字
movswq 字符号扩展传送到四字
movslq 双字符号扩展传送到四字
cltq %rax<-符号扩展(%eax) 把%eax符号扩展到%rax

cltq只能作用于%eax和%rax

对比上述两个表,发现为什么没有movzlq?
绝大多数情况下,mov只会改变指定的寄存器字节或内存,但是对于movl来说,当它的目的为寄存器时,那么除了指定要改变的部分外,还会自动将该寄存器的高4字节置0,所以以寄存器为目的的movl,其作用就相当于movzlq。

另外注意,当涉及强制类型转化的时候,既涉及数据size的转换,又涉及数据有无符号的转换时,先转换大小,再转化符号。

你可能感兴趣的:(csapp,汇编,学习方法)