目录
一、寄存器的种类
二、mov指令
三、lea指令
四、跳转指令
五、压栈/弹栈指令
六、sub/add指令
80386有如下通用寄存器:
mov后的字母表示操作数的长度
使用mov指令可以在寄存器与寄存器之间、内存与寄存器之间传送数据
mov指令可以根据目的操作数的大小来决定传送的字节数
举例:movl $4, %eax 执行的是将立即数4送入到寄存器eax中;
movl %ebx, %eax 执行的是将寄存器ebx中的值送入寄存器eax中;
movl $values,%eax 表示将values的首地址送入寄存器eax中;
movl values,%eax 表示将以values为首地址共四个字节单元表示的值送入到寄存器eax中;
与查看数据相关的指令
--print &value,查看value变量在内存中的地址
--x/4bt 查看内存内容(b表示单字节,h表示双字节,w表示四字 节,g表示八字节)
x 按十六进制格式显示变量,a 按十六进制格式显示变量。
u 按十六进制格式显示无符号整型;o 按八进制格式显示变量。
t 按二进制格式显示变量;d 按十进制格式显示变量
c 按字符格式显示变量;f 按浮点数格式显示变量
s 按照字符串格式显示变量
汇编代码的格式: “ 指令 源操作数 ,目的操作数 ”
示例:movl $8 , %eax
操作数:立即数(immediate)、寄存器(register)、存储器(memory)
注意:CPU计算总是仅从寄存器直接存/取数据
lea 指令是mov 指令的变形
lea 指令形式是从存储器读数据到寄存器,但实际并没有引用存储器,而是将有效地址写入目的操作数(必须是寄存器)
leal S,D 表示D <---&S,将S的地址给D
据说,Intel对于设计出LEA指令颇为得意,LEA指令可以在一个时钟周期内完成,执行效率高;
lea不在ALU里执行,而是在AGU(address generation unit)里执行,可提高并行效率;
如:加法需要1~3个时钟周期,乘法一般需要>10个时间周,除法需要几十甚至上百个时间周期
可以模拟一些三元运算
例如:%ebx =% eax +% edx,不使用lea需要多条指令,而使用lea: lea (%eax,%edx,1), %ebx
lea指令和mov指令的辨析
movl $立即数a,size(%register)是指将立即数a存放到在内存中最终地址为寄存器%register中的值 + size中的单元去
注:括号内的是寄存器,括号外size是偏移值,可为负数。
注意:push $value表示将value的首地址压入栈中
push与pop也可以自动根据操作数的长度来分配入栈/出栈时栈顶指针需要减小/增大的地址长度
1008.s
在调试过程中输入“p value1”即可查看value1的值,输入“p &value1”即可查看地址(p是print的缩写)
此时用p来查看value2的值默认的是打印四个字节(即会将后两个字节中的数据打印出来),所以value2会是0x??030002(根据value2的值可以算得为0x00030002)
分析“movl %ecx, value2”这条指令,此时value2代表的是value2所处单元的首地址,该条指令代表的就是从寄存器ecx中取出的四个字节的数据复制到以value2所处单元的首地址为首的四个内存单元
输入“p $ eax”可以查看寄存器eax中的值
1009.s
先根据“p &values”得到values的首地址,再输入“x /44bx values首地址”查看以values为首地址共11*4个字节的单元的数据,