ia-32汇编笔记

1  汇编语言中test的用法


为举例方便说一下jnz和jz

    测试条件
JZ   ZF=1
JNZ  ZF=0
即Jz=jump if zero (结果为0则设置ZF零标志为1,跳转)
Jnz=jump if not zero

test属于逻辑运算指令

功能: 执行BIT与BIT之间的逻辑运算
     测试(两操作数作与运算,仅修改标志位,不回送结果).
Test对两个参数(目标,源)执行AND逻辑操作搜索,并根据结果设置标志寄存器,结果本身不会保存。TEST AX,BX 与 AND AX,BX 命令有相同效果

语法: TEST r/m,r/m/data
影响标志: C,O,P,Z,S(其中C与O两个标志会被设为0)

运用举例:
1.Test用来测试一个位,例如寄存器:

test eax, 100b;          b后缀意为二进制
jnz  ******;             如果eax右数第三个位为1,jnz将会跳转

我是这样想的,jnz跳转的条件是ZF=0,ZF=0意味着ZF(零标志)没被置位,即逻辑与结果为1.

2.Test的一个非常普遍的用法是用来测试一方寄存器是否为空:

test ecx, ecx
jz somewhere

如果ecx为零,设置ZF零标志为1,Jz跳转


2   loadsb是什么指令


 loadsb:用于目的地址的内容读到源地址,即目标地址为:ES:DI,源地址为DS:SILODS
LODSB
LODSW
LODSD

将字符串装入累加器(Load Accumulator from string)

将由DS:E(SI)寻址的一个内存字节或字装入累加器(AL, AX 或 EAX)中,如果使用LODS,必须

指定内存操作数.LODSB将一个字节装入AL,LODSW将一个字装入AX.IA-32处理器的LODSD将一

个双字装入EAX.(E)SI根据操作数大小和方向标志值自动增减.如果方向标志(DF)=1,ESI增

加,如果DF=0,ESI减少

   


3汇编中div指令的使用



当除数是字节 也就是8位的时候  被除数必须是16位  被除数存放在ax寄存器中  除数放在bl中

除到得 结果是 商是8位放在al中 余数放在ah中

例子

mov ax,0006h

mov bl,02h

div bl

使用debug调试时 查看结果

执行div bl

查看ax的结果是 0003

可看出 ah=00

al=03

商是3 余数是0

当除数是字 也就是16位的时候  被除数必须是32位  被除数低16位存放在ax寄存器中 ,高16位放在dx寄存器中   

除到得 结果是 商是16位放在ax中 余数放在dx中


 mov dx,0001h
 mov ax,83a1h  
 mov bx,0064h  
 div bx

4      EIP、ESP、EBP

   

1.EIP
2.ESP
3.EBP
1.EIP寄存器里存储的是CPU下次要执行的指令的地址。
也就是调用完fun函数后,让CPU知道应该执行main函数中的printf("函数调用结束")语句了。
2.EBP寄存器里存储的是是栈的栈底指针,通常叫栈基址,这个是一开始进行fun()函数调用之前,由ESP传递给EBP的。(在函数调用前你可以这么理解:ESP存储的是栈顶地址,也是栈底地址。)
3.ESP寄存器里存储的是在调用函数fun()之后,栈的栈顶。并且始终指向栈顶。

堆栈是一种简单的数据结构,是一种只允许在其一端进行插入或删除的线性表。
允许插入或删除操作的一端称为栈顶,另一端称为栈底,对堆栈的插入和删除操作被称入栈和出栈。

有一组CPU指令可以实现对进程的内存实现堆栈访问。其中,POP指令实现出栈操作,PUSH指令实现入栈操作。

CPU的ESP寄存器存放当前线程的栈顶指针,

EBP寄存器中保存当前线程的栈底指针。

CPU的EIP寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。

esp和ebp区别

问题:
push ebp
mov esp, ebp
干嘛要这样?

--------------------------------------------------------------------------------
esp是堆栈指针 
ebp是基址指针 

那两条指令的意思是 将栈顶指向 ebp 的地址 
--------------------------------------------------------------- 

楼主写的好像是要用GCC来编译的汇编? 

push    ebp     ;ebp入栈 
mov     ebp, esp ;因为esp是堆栈指针,无法暂借使用,所以得用ebp来存取堆栈
sub     esp, 4*5 ;下面的wsprintf一共使用了5个参数,每个参数占用4个字节,所以要入栈4*5个字节 
push    1111 
push    2222 
push    3333 
push    offset szFormat 
push    offset szOut 
call    wsprintf       ;调用wsprintf 
add     esp, 4*5     ;堆栈使用完毕,“还”回4*5个字节给系统 
... 
mov     esp, ebp     ;恢复esp的值 
pop     ebp        ;ebp出栈 
ret 

主要是用来保存/恢复堆栈,以便传递参数给函数。 
在MASM里面,有一条更方便的语句,就是invoke, 使用它后,你就不用自己做这些事情了。 
--------------------------------------------------------------- 
esp始终指向栈顶,ebp是在堆栈中寻址用的



5   iretd


iretd

当一个中断服务程序执行完毕时,CPU将恢复被中断的现场,返回到引起中断的程序中。为了实现此项功能,指令系统提供了一条专用的中断返回指令。

该指令执行的过程基本上是INT指令的逆过程,具体如下:
◆、从栈顶弹出内容送入IP;
◆、再从新栈顶弹出内容送入CS;
◆、再从新栈顶弹出内容送入标志寄存器;
对80386及其以后的CPU,指令IRETD从栈顶弹出32位内容送入EIP。
中断和子程序调用之间有其相似和不同之处。它们的工作过程非常相似,即:暂停当前程序的执行,转而执行另一程序段,当该程序段执行完时,CPU都自动恢复原程序的执行。

它们的主要差异有:
◆、子程序调用一定是程序员在编写源程序时事先安排好的,是可知的,而中断是由中断源根据自身的需要产生的,是不可预见的(用指令INT引起的中断除外);
◆、子程序调用是用CALL指令来实现的,但没有调用中断的指令,只有发出中断请求的事件(指令INT是发出内部中断信号,而不要理解为调用中断服务程序);
◆、子程序的返回指令是RET,而中断服务程序的返回指令是IRET/IRETD。
◆、在通常情况下,子程序是由应用系统的开发者编写的,而中断服务程序是由系统软件设计者编写的。


6      汇编指令(out)语法


 

以下无语法错误的是? 1.out ax,30h 2.out bx,al 3.out al,dx 4.out 30h,ah 给出详细的解释!

四个都错误 语法是out port,acc 1、要是交换下操作数,倒是正确的。或者改为in指令。 2、bx错误,port端口号超过255时,应该放到dx中。 3、还是交换下操作数就对了,或者改为in指令。 4、ah错误,如果输出的数据是8位,则应该使用al寄存器。 总结: 语法格式:out port,acc 1)port为端口地址。可以是0-0ffffh 小于255时,可用直接寻址或间接寻址;大于255, 如果端口号在0-255(0ffh)之间,可用直接寻址或间接寻址,用于间接寻址的寄存器是DX。 比如 直接寻址:out 30h,al 间接寻址:mov dx,30h out dx,al 如果超过255(0ffh)必须用间接寻址。比如: mov dx,378h mov dx,al 2)acc必须是累加器。外设是8位端口时,用AL寄存器;外设为16为端口时,用AX寄存器。 比如: out dx,al ;将al中的字节数据通过dx所指出的端口向外设输出 out dx,ax ;将ax中的字数据通过dx所指出的端口向外设输出


你可能感兴趣的:(汇编,32位,汇编语言)