基本汇编指令

目录

  • 一,eax寄存器
  • 二,eip寄存器
  • 三,leave指令
  • 四,ret指令
  • 五,call指令
  • 六, pop和push指令
    • ①**push寄存器:将一个寄存器中的数据入栈**
    • ②**pop寄存器:出栈用一个寄存器接收数据**
  • 七,test指令
  • 八,cmp指令
  • 九,mul和imul
    • ①mul是无符号数相乘
    • ②imul是带符号数相乘
    • ③十六进制数乘法(这里和汇编无关了,自己加的)

一,eax寄存器

eax,32位寄存器,ax代表十六位,al代表低八位,ah代表高八位,
并且函数返回值一般使用eax存放,al的l是low低八位,ah的h是high高八位
如图
基本汇编指令_第1张图片

二,eip寄存器

eip存放将要执行的指令的地址

三,leave指令

leave指令等价于
movl %ebp , %esp
popl %ebp

起到退栈作用!!

四,ret指令

把返回地址放到eip寄存器中,然后再返回

五,call指令

保存下一条指令的地址,并转向被调用函数
基本汇编指令_第2张图片

六, pop和push指令

push和pop是用来操作栈的2个指令。

push寄存器:将一个寄存器中的数据入栈

push %ebp # 等价于R[%esp] <- R[%esp] - 4 , 把栈指针下移 
				  #  M[R[%esp]] = R[%ebp] , 把数据入栈,就是把旧的ebp的值入栈

pop寄存器:出栈用一个寄存器接收数据

popl %ebp # 从栈中弹出一个数据并用寄存器接收
				  # R[%ebp] = M[R[%esp]]
				  # R[%esp] = R[%esp] + 4

七,test指令

相当于两个操作数相“与”,不改变原操作数
例子:
testb $0x1 , %al
#判断al最后一位是否是1,如果ZF = 0 , 则说明al最后一位是1
,否则为0
②寄存器自身相与
testb %al , %al
#作用:判断al是否为0,
#如果ZF=1,则al就是0
#如果SF=0且ZF=0,则说明al是正数
#如果SF=1,则说明al是负数
#SF判断方法:结果的符号位是1,则SF=1,结果符号位是0,SF=0

八,cmp指令

cmpl %eax,%ebx
R【ebx】-【eax】,就是把第二个数减去第一个数
下面是我的理解
如果第二个数<=第一个数,就是跳转到jbe或jle,然后这样去比较就

简单的一段汇编代码和C语句

int nn_sum(int n){
	int i;
	int result = 0 ;
	for ( i = 1 ; i <= n ; i++ )
		result += i ;
	return result;	
}
movl 8(%ebp) , %ecx
movl $0 , %eax
movl $1 , %edx
cmp %ecx , %edx
jg .L2
.L1 
	addl %edx , %eax
	addl $1 , %edx
	jle .L1
.L2

九,mul和imul

①mul是无符号数相乘

mul只能给出一个操作数
只给出1个操作数src,另一个操作数隐含在累加器al/ax/eax中,
计算过程:

把src和累加器相乘,结果存放在ax(16位)或dx-ax(32位时)
dx-ax表示高16位放在dx,低16位放在ax

②imul是带符号数相乘

若指令给出2个操作数src和dst,则dst和src相乘,结果放在dst中,imul指令把2个带符号数相乘,结果>只取低n位

③十六进制数乘法(这里和汇编无关了,自己加的)

和十进制那样正常乘,但是乘了之后如果超过16则把那个数减去x个16,看那个x是多少,
比如2 * A,就是20,个16 + 一个4,就是进1,该位写4
如果是4 * A ,那就是40,2个16 + 一个6,就是进2,该位写6

你可能感兴趣的:(计算机系统基础,汇编语言,反汇编,汇编语言,汇编指令)