免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
X86匯編學習小結
生成匯編代碼
比如,一個簡單的函數(shù):
// hello.cvoid func(){}
如何得到相應的匯編代碼呢?
gcc -S hello.c
hello.s
clang -S hello.c
hello.s
gcc -S -masm=intel hello.c
hello.s
cl /FAs /C hello.c
hello.asm
看些結果:
gcc 4.5.2, Ubuntu11.04 X86 默認的匯編
.globl func .type func, @functionfunc: pushl %ebp movl %esp, %ebp popl %ebp retclang 2.8, Ubuntu11.04 X86
.globl func .align 16, 0x90 .type func,@functionfunc: pushl %ebp movl %esp, %ebp popl %ebp ret.Ltmp0: .size func, .Ltmp0-funcgcc 4.5.2, Ubuntu11.04 X86 Intel格式的匯編
.globl func .type func, @functionfunc: push ebp mov ebp, esp pop ebp retcl 16 (即VC10), Windows Xp
_func PROC; 1 : void func(){} push ebp mov ebp, esp pop ebp ret 0_func ENDP順便看一個Sun Studio 11: C 5.8 compiler,SPARC架構(服務器來自unix-center)
.global func .type func,#functionfunc: save %sp,-96,%sp jmp %i7+8 restore...以及GCC 4.0.1,SPARC架構(服務器來自unix-center)
.global funcfunc: retl ! Result = nop .type func,2 .size func,(.-func)...
這些東西太復雜了,關注點只能限制到X86架構了。先看一下X86下常用的兩種匯編有哪些不同。
X86匯編語言 差異
X86 下常用的匯編有 AT&T 與 Intel 兩種(fix me?),二者在語法上有一定的差異:
注:本節(jié)內容來自http://oss.org.cn,文字和格式進行了重新整理。
前綴/后綴
區(qū)別:
Intel語法
AT&T語法
寄存器
加前綴 %
立即數(shù)
加前綴 $
十六進制
加后綴h
數(shù)字前加 0x
二進制
加后綴b
例子:
Intel語法
AT&T語法
mov eax,8
movl $8,%eax
mov ebx,0ffffh
movl $0xffff,%ebx
int 80h
int $0x80
操作數(shù)的方向
二者方向正好相反
Intel語法,第一個是目的操作數(shù),第二個是源操作數(shù)。
AT&T中,第一個數(shù)是源操作數(shù),第二個數(shù)是目的操作數(shù)。(更符合閱讀習慣哈)
例子:
Intel語法(<==)
AT&T語法(==>)
mov eax,[ecx]
movl (%ecx),%eax
內存單元操作數(shù)
在Intel的語法中,基寄存器用“[]”括起來
而在AT&T中,用“()”括起來。
Intel
AT&T
mov eax,[ebx+5]
movl 5(%ebx),%eax
間接尋址方式
Intel的指令格式是segreg:[base+index*scale+disp]
AT&T的格式是%segreg:disp(base,index,scale)
Intel語法
AT&T語法
指令 foo,segreg:[base+index*scale+disp]
指令 %segreg:disp(base,index,scale),foo
mov eax,[ebx+20h]
Movl 0x20(%ebx),%eax
add eax,[ebx+ecx*2h]
Addl (%ebx,%ecx,0x2),%eax
lea eax,[ebx+ecx]
Leal (%ebx,%ecx),%eax
sub eax,[ebx+ecx*4h-20h]
Subl -0x20(%ebx,%ecx,0x4),%eax
操作碼的后綴
在AT&T的操作碼后加后綴,“l(fā)”(long,32位),“w”(word,16位),“b”(byte,8位)
在Intel的語法中,在操作數(shù)的前加byte ptr、 word ptr 或 dword ptr
例子:
Intel語法
AT&T語法
Mov al,bl
movb %bl,%al
Mov ax,bx
movw %bx,%ax
Mov eax,ebx
movl %ebx,%eax
Mov eax, dword ptr [ebx]
movl (%ebx),%eax
找個例子看看
hello.c
int func(int i){ return 2 * i;}int main(){ int s = func(255); return 0;}hello.s (gcc4.5.2, x86/ubuntu11.04)
func:
pushl   %ebp
將ebp內容壓棧保存
movl    %esp, %ebp
movl    8(%ebp), %eax
注意到立即數(shù)255在main中壓棧后,先后有IP和本函數(shù)內的ebp壓棧,故,棧頂+8指向立即數(shù)255
addl    %eax, %eax
乘法操作變成了加法,eax存放返回值
popl    %ebp
ebp出棧
ret
函數(shù)返回,(IP出棧)
main:
pushl   %ebp
將ebp內容壓棧保存,
movl    %esp, %ebp
將棧頂保存到ebp中
subl    $20, %esp
棧頂下移20字節(jié),用來保存局部變量
movl    $255, (%esp)
將立即數(shù)255放入棧頂所指位置
call    func
調用函數(shù)func,(此時將下條指令地址IP壓入棧中)
movl    %eax, -4(%ebp)
將func的返回值放入局部變量中(-4(%ebp)就是變量s的位置)
movl    $0, %eax
0送入eax,準備返回值
leave
leave等價于 movl %ebp,%esp 和 popl %ebp
ret
參考
http://oss.org.cn/kernel-book/ch02/2.6.1.htm
http://bbs.bccn.net/thread-106533-1-1.html
==================================================================================================
X86 匯編語言中CPU上的通用寄存器簡要說明
eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 匯編語言中CPU上的通用寄存器的名稱,是32位的寄存器。如果用C語言來解釋,可以把這些寄存器當作變量看待。
比方說:add eax,-2 ;   //可以認為是給變量eax加上-2這樣的一個值。
這些32位寄存器有多種用途,但每一個都有“專長”,有各自的特別之處。
EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。
EBX 是"基地址"(base)寄存器, 在內存尋址時存放基地址。
ECX 是計數(shù)器(counter), 是重復(REP)前綴指令和LOOP指令的內定計數(shù)器。
EDX 則總是被用來放整數(shù)除法產(chǎn)生的余數(shù)。
ESI/EDI 分別叫做"源/目標索引寄存器"(source/destination index),因為在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目標串.
EBP 是"基址指針"(BASE POINTER), 它最經(jīng)常被用作高級語言函數(shù)調用的"框架指針"(frame pointer). 在破解的時候,經(jīng)??梢钥匆娨粋€標準的函數(shù)起始代碼:
push ebp ; 保存當前ebp
mov ebp,esp ; EBP設為當前堆棧指針
sub esp, xxx ; 預留xxx字節(jié)給函數(shù)臨時變量.
...
這樣一來,EBP 構成了該函數(shù)的一個框架, 在EBP上方分別是原來的EBP, 返回地址和參數(shù). EBP下方則是臨時變量. 函數(shù)返回時作 mov esp,ebp/pop ebp/ret 即可.
ESP 專門用作堆棧指針,被形象地稱為棧頂指針,堆棧的頂部是地址小的區(qū)域,壓入堆棧的數(shù)據(jù)越多,ESP也就越來越小。 在32位平臺上,ESP每次減少4字節(jié)。
esp:寄存器存放當前線程的棧頂指針
ebp:寄存器存放當前線程的棧底指針
eip:寄存器存放下一個CPU指令存放的內存地址,當CPU執(zhí)行完當前的指令后,從EIP寄存器中讀取下一條指令的內存地址,然后繼續(xù)執(zhí)行。
一般寄存器:AX、BX、CX、DX
AX:累積暫存器,BX:基底暫存器,CX:計數(shù)暫存器,DX:資料暫存器
索引暫存器:SI、DI
SI:來源索引暫存器,DI:目的索引暫存器
堆疊、基底暫存器:SP、BP
SP:堆疊指標暫存器,BP:基底指標暫存器
EAX、ECX、EDX、EBX:為ax,bx,cx,dx的延伸,各為32位元
ESI、EDI、ESP、EBP:為si,di,sp,bp的延伸,32位元
棧的基本模型
參數(shù)N
↓高地址
參數(shù)…
函數(shù)參數(shù)入棧的順序與具體的調用方式有關
參數(shù) 3
參數(shù) 2
參數(shù) 1
EIP
返回本次調用后,下一條指令的地址
EBP
保存調用者的EBP,然后EBP指向此時的棧頂。
臨時變量1
臨時變量2
臨時變量3
臨時變量…
臨時變量5
↓低地址
===========================================================================
80x86指令系統(tǒng)
80x86指令系統(tǒng),指令按功能可分為以下七個部分。
(1) 數(shù)據(jù)傳送指令。
(2) 算術運算指令。
(3) 邏輯運算指令。
(4) 串操作指令。
(5) 控制轉移指令。
(6) 處理器控制指令。
(7) 保護方式指令。
3.3.1數(shù)據(jù)傳送指令
數(shù)據(jù)傳送指令包括:通用數(shù)據(jù)傳送指令、地址傳送指令、標志寄存器傳送指令、符號擴展指令、擴展傳送指令等。
一、通用數(shù)據(jù)傳送指令
1傳送指令
傳送指令是使用最頻繁的指令,格式:MOV DEST,SRC
功能:把一個字節(jié),字或雙字從源操作數(shù)SRC傳送至目的操作數(shù)DEST。
傳送指令允許的數(shù)據(jù)流方向見圖311。
圖 3.11  傳送指令數(shù)據(jù)流
由上圖可知,數(shù)據(jù)允許流動方向為:通用寄存器之間、通用寄存器和存儲器之間、通用寄存器和段寄存器之間、段寄存器和存儲器之間,另外還允許立即數(shù)傳送至通用寄存器或存儲器。但在上述傳送過程中,段寄存器CS的值不能用傳送指令改變。
例 3.12CPU內部寄存器之間的數(shù)據(jù)傳送。
MOV AL,DH   ?。籄L←DH    (8位)
MOV DS,AX    ;DS←AX    (16位)
MOV EAX,ESI  ??;EAX←ESI   (32位)
例 3.13CPU內部寄存器和存儲器之間的數(shù)據(jù)傳送。
MOV [BX],AX       ;間接尋址     (16位)
MOV EAX,[EBX+ESI]   ;基址變址尋址   (32位)
MOV AL,BLOCK      ;BLOCK為變量名,直接尋址(8位)
例 3.14立即數(shù)送通用寄存器、存儲器。
MOV EAX,12345678H  ?。籈AX←12345678H   (32位)
MOV [BX],12H      ;間接尋址      (8位)
MOV AX,1234H;AX←1234H(16位)
使用該指令應注意以下問題:
·源和目的操作數(shù)不允許同時為存儲器操作數(shù);
·源和目的操作數(shù)數(shù)據(jù)類型必須一致;
·源和目的操作數(shù)不允許同時為段寄存器;
·目的操作數(shù)不允許為CS和立即數(shù);
·當源操作數(shù)為立即數(shù)時,目的操作數(shù)不允許為段寄存器;
·傳送操作不影響標志位。
2擴展傳送指令
格式:MOV SX DEST,SRC
MOV ZX DEST,SRC
功能:將源操作數(shù)由8位擴展到16位送目的操作數(shù),或由16位擴展到32位送目的操作數(shù)。其中MOVSX是按有符號數(shù)擴展,MOVZX是按無符號數(shù)擴展。無符號數(shù)或正數(shù)高位擴展為0,負數(shù)高位擴展為全“1”。
例 3.15帶符號數(shù)擴展
MOV BL,80H  ; -128
MOVSX AX,BL ??; 將80H擴展為FF80H后送AX中。
例 3.16無符號數(shù)擴展
MOV BL,80H  ; 128
MOVZX AX,BL ?。弧?0H擴展為0080H后送AX中。
使用該指令應注意以下問題:
·目的操作數(shù)應為16位或32位通用寄存器;
·源操作數(shù)長度須小于目的操作數(shù)長度,為8位或16位通用寄存器或存儲器操作數(shù);
·擴展傳送操作不影響標志位。
3交換指令
(1) 格式:XCHG OPR1,OPR2
功能:交換操作數(shù)OPR1和OPR2的值,操作數(shù)數(shù)據(jù)類型為字節(jié)、字或雙字。允許通用寄存器之間,通用寄存器和存儲器之間交換數(shù)據(jù)。
例 3.17
XCHG AX,BX;通用寄存器之間交換數(shù)據(jù)(16位)
XCHG ESI,EDI;通用寄存器之間交換數(shù)據(jù)(32位)
XCHG BX,/[SI/];通用寄存器和存儲器之間交換數(shù)據(jù)(16位)
XCHG AL,/[BX/];通用寄存器和存儲器之間交換數(shù)據(jù)(8位)
使用該指令應注意以下問題:
·操作數(shù)OPR1和OPR2不允許同為存儲器操作數(shù);
·操作數(shù)數(shù)據(jù)類型必須一致;
·交換指令不影響標志位。
如要實現(xiàn)存儲器操作數(shù)交換,可用如下指令實現(xiàn):
MOV AL,BLOCK1
XCHG AL,BLOCK2
MOV BLOCK1,AL
(2) 格式:BSWAP REG
功能:將32位通用寄存器中,第1個字節(jié)和第4個字節(jié)交換,第2個字節(jié)和第3個字節(jié)交換。
例 3.18
MOV EAX,44332211H
BSWAP EAX;EAX=11223344H
使用該指令應注意以下問題:
·操作數(shù)為32位通用寄存器;
·交換指令不影響標志位。
二、堆棧操作指令
1壓棧指令
(1) 格式:PUSH SRC
功能:將源操作數(shù)壓下堆棧,源操作數(shù)允許為16位或32位通用寄存器、存儲器和立即數(shù)以及16位段寄存器。當操作數(shù)數(shù)據(jù)類型為字類型,壓棧操作使SP值減2;當數(shù)據(jù)類型為雙字類型,壓棧操作使SP值減4。
例 3.19
PUSH AX         ?。煌ㄓ眉拇嫫鞑僮鲾?shù)入棧(16位)
PUSH EBX          ;通用寄存器操作數(shù)入棧(32位)
PUSH [SI]         ;存儲器操作數(shù)入棧(16位)
PUSH DWORD PTR [DI]    ;存儲器操作數(shù)入棧(32位)
PUSHW 0A123H        ;立即數(shù)入棧(16位)
PUSHD 20H        ??;立即數(shù)入棧(32位)
(2) 格式:PUSHA
PUSHAD
功能:PUSHA將16位通用寄存器壓入堆棧,壓棧順序為AX,CX,DX,BX,SP,BP,SI,DI。
PUSHAD將32位通用寄存器壓入堆棧,壓棧順序為EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI。
2出棧指令
(1) 格式:POP DEST
功能:從棧頂彈出操作數(shù)送入目的操作數(shù)。目的操作數(shù)允許為16或32位通用寄存器、存儲器和16位段寄存器。當操作數(shù)數(shù)據(jù)類型為字類型,出棧操作使SP加2;當操作數(shù)數(shù)據(jù)類型為雙字類型,出棧操作使SP加4。
例 3.20
POP AX         ??;操作數(shù)出棧送寄存器(16位)
POP ECX          ;操作數(shù)出棧送寄存器(32位)
POP [BX]        ?。徊僮鲾?shù)出棧送存儲器(16位)
POP DWORD PTR [SI]   ??;操作數(shù)出棧送存儲器(32位)
(2) 格式:POPA
POPAD
功能:POPA從堆棧移出16字節(jié)數(shù)據(jù),并且按順序存入寄存器DI,SI,BP,SP,BX,DX,CX,AX中。
POPAD從堆棧移出32字節(jié)數(shù)據(jù),并且按順序存入寄存器EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX中。
使用堆棧操作指令應注意以下問題。
(1) 目的操作數(shù)不允許為CS以及立即數(shù)。
(2) 堆棧操作指令不影響標志位。
三、地址傳送指令
(1) 格式:LEA REG,MEM
功能:將源操作數(shù)的有效地址傳送到通用寄存器,操作數(shù)REG為16位或32位通用寄存器,源操作數(shù)為16位或32位存儲器操作數(shù)。
例 3.21
LEA BX,BLOCK;將BLOCK的有效地址傳送到BX中(16位)
LEA EAX,/[EBX/];將EBX內容(有效地址)傳送到EAX中(32位)
(2) 格式LDS(ES,F(xiàn)S,GS,SS)REG,MEM
功能:根據(jù)源操作數(shù)指定的偏移地址,在數(shù)據(jù)段中取出段地址和偏移地址分別送指定的段寄存器和指定的通用寄存器。
例 3.22
LES BX,[SI]       ?。粚?2位地址指針分別送ES和BX
LSS EAX,[EDI]      ??;將48位地址指針分別送SS和EAX
例 3.23
DATA1  DD buff
LDS BX,DATA1;將buff的32位地址指針分別送DS和BX
地址傳送指令對標志位無影響。
四、標志寄存器傳送指令
(1) 格式:LAHF
SAHF
功能:LAHF將標志寄存器中低8位送AH中。SAHF將AH中內容送標志寄存器中低8位。
(2) 格式:PUSHF
POPF
功能:PUSHF將標志寄存器低16位內容壓入堆棧,SP←SP-2。POPF將當前棧頂一個字傳送到標志寄存器低16位中,SP←SP+2。
(3) 格式:PUSHFD
POPFD
功能:PUSHFD將標志寄存器32位內容壓入堆棧SP←SP-4。POPFD將當前棧頂一個雙字傳送到32位標志寄存器中,SP←SP+4。
上述SAHF,POPF,POPFD均影響相應的標志寄存器內容。
五、查表指令
格式:XLAT
功能:將寄存器AL中的內容轉換成存儲器表格中的對應值。實現(xiàn)直接查表功能。
XLAT指令規(guī)定:BX寄存器存放表的首地址,AL寄存器中存放表內偏移量,執(zhí)行XLAT指令,以段寄存器DS的內容為段基址,有效地址為BX和AL內容之和,取出表中一個字節(jié)內容送AL中。
例 3.24內存中有一起始地址為TABLE的編碼表,試編程將表中順序號為4的存儲單元內容送寄存器AL。
·MODEL SMALL
·DATA
TABLE      DB 11H,22H,33H,44H,55H 某編碼表
·CODE
·STARTUP
MOV AL,4           ;AL←4
MOV BX,OFFSET TABLE    ?。籅X←TABLE表首地址
XLAT            ?。唤Y果在AL中,AL=55H
·EXIT
END
查表指令不影響標志位。
六、符號擴展指令
(1) 格式:CBW
功能:將AL中8位帶符號數(shù),進行帶符號擴展為16位,送AX中。帶符號擴展是指對正數(shù)高位擴展為全“0”,對負數(shù)高位擴展為全“1”。
例 3.25AL=55H 經(jīng)CBW擴展后 AX=0055H
AL=A5H 經(jīng)CBW擴展后 AX=FFA5H
(2) 格式:CWD
功能:將AX中16位帶符號數(shù),進行帶符號擴展為32位,送DX和AX中。高16位送DX中,低16位送AX中。
(3) 格式:CWDE
功能:將AX中16位帶符號數(shù),進行帶符號擴展為32位,送EAX中。
(4) 格式:CDQ
功能:將EAX中32位帶符號數(shù),進行帶符號擴展為64位,送EDX和EAX中。低32位送EAX中,高32位送EDX中。
符號擴展指令對標志位無影響。
3.3.2 算術運算指令
80x86指令包括加、減、乘、除四種基本算術運算操作及十進制算術運算調整指令。二進制加、減法指令,帶符號操作數(shù)采用補碼表示時,無符號數(shù)和帶符號數(shù)據(jù)運算可以使用相同的指令。二進制乘、除法指令分帶符號數(shù)和無符號數(shù)運算指令。
一、加法指令
格式:ADDDEST,SRC
ADCDEST,SRC
功能:ADD是將源操作數(shù)與目的操作數(shù)相加,結果傳送到目的操作數(shù)。ADC是將源操作數(shù)與目的操作數(shù)以及CF(低位進位)值相加,結果傳送到目的操作數(shù)。
源操作數(shù)可以是通用寄存器、存儲器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲器操作數(shù)。
ADD,ADC指令影響標志位為OF,SF,ZF,AF,PF,CF。
例 3.26
MOV AX,9876H
ADD AH,AL;AX=0E76H CF=1 SF=0O F=0 ZF=0 AF=0 PF=0
ADC AH,AL;AX=8576H CF=0 SF=1O F=1 ZF=0 AF=1 PF=0
二、減法指令
格式:SUB DEST,SRC
SBB DEST,SRC
功能:SUB將目的操作數(shù)減源操作數(shù),結果送目的操作數(shù)。SBB將目的操作數(shù)減源操作數(shù),還要減CF(低位借位)值,結果送目的操作數(shù)。
源操作數(shù)可以是通用寄存器、存儲器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲器操作數(shù)。
SUB,SBB指令影響標志位為OF,SF,ZF,AF,PF,CF。
例 3.27
MOV AX, 9966H;AX=9966H
SUB AL, 80H;AL=E6HCF=1SF=1OF=1ZF=0AF=0PF=0
SBB AH, 80H;AH=18HCF=0SF=0OF=0ZF=0AF=0PF=1
三、加1減1指令
格式:INC DEST
DEC DEST
功能:INC指令將目的操作數(shù)加1,結果送目的操作數(shù)。DEC指令將目的操作數(shù)減1,結果送目的操作數(shù)。目的操作數(shù)為通用寄存器或存儲器操作數(shù)。
INC,DEC指令影響標志位為OF,SF,ZF,AF,PF。
例 3.28
INC BL;BL←BL+1
INC AX;AX←AX+1
INC WORDPTR [BX];存儲器操作數(shù)加1
DEC BYTE PTR [SI];存儲器操作數(shù)減1
DEC EAX;EAX←EAX-1
四、比較指令
(1) 格式:CMP DEST,SRC =============這個是intel格式
功能:目的操作數(shù)減源操作數(shù),結果不回送。源操作數(shù)為通用寄存器、存儲器和立即數(shù)。目的操作數(shù)為通用寄存器、存儲器操作數(shù)。
CMP指令影響標志位為OF,SF,ZF,AF,PF,CF。
例 3.29
CMP CX,3
CMP WORD PTR [SI],3
CMP AX,BLOCK
執(zhí)行比較指令后,對狀態(tài)標志位影響見表3.2。對于兩個數(shù)的比較(AX-BX)有以下3種情況。
表 3.2 CMP指令對標志位的影響
· 兩個正數(shù)比較,使用SF標志位判斷。
SF=0,則AX≥BX,若ZF=1,則AX=BX
SF=1,則AX<BX
· 兩個無符號數(shù)比較,使用CF標志位判斷。
CF=0,則AX≥BX,若ZF=1,則AX=BX
CF=1,則AX<BX
· 兩個負數(shù)比較,使用SF標志位判斷。
SF=0,則AX≥BX,若ZF=1,則AX=BX
SF=1,則AX<BX
· 兩個異符號數(shù)比較。
如果OF=0,仍可用SF標志判斷大小。
如果OF=1,說明結果的符號位發(fā)生錯誤,所以
SF=0,則AX<BX
SF=1,則AX>BX
綜上所述:兩個異號數(shù)比較
當OF=0,SF=0,則AX>BX
SF=1,則AX<BX
當OF=1,SF=0,則AX<BX
SF=1,則AX>BX
用邏輯表達式表示為:
若OF∨-SF=0,則AX>BX
若OF∨-SF=1,則AX<BX
(2) 格式:CMPXCHGDEST,REG
功能:目的操作數(shù)減源操作數(shù),
如果DEST=SRC,則SRC→DEST。
如果DEST≠SRC,則DEST→ACC(AL,AX,EAX)。
源操作數(shù)允許為通用寄存器。目的操作數(shù)可以為通用寄存器,存儲器操作數(shù)。
CMPXCHG影響標志位為OF,SF,ZF,AF,PF,CF。
(3) 格式:CMPXCHG8BMEM
功能:EDX:EAX中值減存儲器操作數(shù)。
如果EDX:EAX=MEM64,則ECX:EBX→MEM64。
如果EDX:EAX≠MEM64,則MEM64→EDX:EAX。
該指令為64位比較交換指令,影響ZF標志位。
例 3.30  CMPXCHG8BQWORDPTR[EBX]
五、交換相加指令
格式:XADDDEST,REG
功能:目的操作數(shù)加源操作數(shù),結果送目的操作數(shù)。原目的操作數(shù)內容送源操作數(shù)。源操作數(shù)允許為通用寄存器。目的操作數(shù)允許為通用寄存器、存儲器操作數(shù)。
XADD指令影響標志位為OF,SF,ZF,AF,PF,CF。
六、求補指令
格式:NEGDEST
功能:對目的操作數(shù)求補,用零減去目的操作數(shù),結果送目的操作數(shù)。目的操作數(shù)為通用寄存器、存儲器操作數(shù)。
NEG指令影響標志位為OF,SF,ZF,AF,PF,CF。
七、乘法指令
(1) 格式:MULSRC
IMULSRC
功能:MUL為無符號數(shù)乘法指令,IMUL為帶符號數(shù)乘法指令。源操作數(shù)為通用寄存器或存儲器操作數(shù)。目的操作數(shù)缺省存放在ACC(AL,AX,EAX)中,乘積存AX,DX:AX,EDX:EAX中。
字節(jié)乘:ALSRC→AX
字乘:AXSRC→DX∶AX
雙字乘:EAXSRC→EDX∶EAX
MUL,IMUL指令執(zhí)行后,CF=OF=0,表示乘積高位無有效數(shù)據(jù);CF=OF=1表示乘積高位含有效數(shù)據(jù),對其它標志位無定義。
例 3.31
MUL BL;字節(jié)乘
MUL WORD PTR [SI];字乘
IMUL BYTE PTR [DI];字節(jié)乘
IMUL DWORD PTR [ECX];雙字乘
如果使用IMUL指令,積采用補碼形式表示。
(2) 格式:IMULDEST,SRC
功能:將目的操作數(shù)乘以源操作數(shù),結果送目的操作數(shù)。目的操作數(shù)為16位或32位通用寄存器或存儲器操作數(shù)。源操作數(shù)為16位或32位通用寄存器、存儲器或立即數(shù)。
源操作數(shù)和目的操作數(shù)數(shù)據(jù)類型要求一致。乘積僅取和目的操作數(shù)相同的位數(shù),高位部分將被舍去,并且CF=OF=1。其它標志位無定義。
(3) 格式:IMUL DEST,SRC1,SRC2
功能:將源操作數(shù)SRC1與源操作數(shù)SRC2相乘,結果送目的操作數(shù)。目的操作數(shù)DEST為16位或32位,允許為通用寄存器。源操作數(shù)SRC1為16位或32位通用寄存器或存儲器操作數(shù)。源操作數(shù)SRC2允許為立即數(shù)。
例 3.32  IMULEAX,[EBX],12H
要求目的操作數(shù)和源操作數(shù)SRC1類型相同,當乘積超出目的操作數(shù)部分,將被舍去,并且使CF=OF=1,在使用這類指令時,需在IMUL指令后加一條判斷溢出的指令,溢出時轉錯誤處理執(zhí)行程序。
八、除法指令
格式:DIV SRC
IDIV SRC
功能:DIV為無符號數(shù)除法,IDIV為帶符號數(shù)除法。源操作數(shù)作為除數(shù),為通用寄存器或存儲器操作數(shù)。被除數(shù)缺省在目的操作數(shù)AX,DX:AX,EDX:EAX中。
字節(jié)除法:AX/SRC商→AL,余數(shù)→AH
字除法:DX·AX/SRC商→AX,余數(shù)→DX
雙字除法:EDX·EAX/SRC商→EAX,余數(shù)→EDX
由于被除數(shù)必須是除數(shù)的雙倍字長,一般應使用擴展指令進行高位擴展。當進行無符號數(shù)除法時,被除數(shù)高位按0擴展為雙倍除數(shù)字長。當進行有符號數(shù)除法時,被除數(shù)以補碼表示??墒褂脭U展指令CBW,CWD,CWDE,CDQ進行高位擴展。例如:
MOV AX,BLOCK
CWD;被除數(shù)高位擴展
MOV BX,1000H
IDIV BX
對于帶符號除法,其商和余數(shù)均采用補碼形式表示,余數(shù)與被除數(shù)同符號。當除數(shù)為零或商超過了規(guī)定數(shù)據(jù)類型所能表示的范圍時,將會出現(xiàn)溢出現(xiàn)象,產(chǎn)生一個中斷類型碼為“0”的中斷。執(zhí)行除法指令后標志位無定義。
九、BCD算術運算
十進制數(shù)在機器中采用BCD碼表示,以壓縮格式存放,即一個字節(jié)存儲2位BCD碼,BCD加減法是在二進制加減運算的基礎上,對其二進制結果進行調整,將結果調整成BCD碼表示形式。
(1) 格式:DAA
功能:將存放在AL中的二進制和數(shù),調整為壓縮格式的BCD碼表示形式。
調整方法:若AL中低4位大于9或標志AF=1(表示低4位向高4位有進位),則
AL+6→AL,1→AF,
若AL中高4位大于9,或標志CF=1,(表示高4位有進位),則
AL+60H→AL,1→CF,
DAA指令一般緊跟在ADD或ADC指令之后使用,影響標志位為SF,ZF,AF,PF,CF。OF無定義。
例 3.33
ADD AL,BL
DAA
(2) 格式:DAS
功能:將存放在AL中的二進制差數(shù),調整為壓縮的BCD碼表示形式。
調整方法:若AL中低4位大于9或標志AF=1(表示低4位向高位借位),則
AL-6→AL,1→AF
若AL中高4位大于9或標志CF=1(表示高4位向高位借位),則
AL-60H→AL,1→CF
DAS指令一般緊跟在SUB或SBB指令之后使用,影響標志位為SF,ZF,AF,PF,CF。OF無定義。
例 3.34
SUB AL,BL
DAS
十、ASCII算術運算
數(shù)字0~9的ASCII碼為30H~39H,機器采用一個字節(jié)存放一位ASCII碼,對于ASCII碼的算術運算是在二進制運算基礎上進行調整。調整指令有加、減、乘、除四種調整指令。
(1) 格式:AAA
功能:將存放在AL中的二進制和數(shù),調整為ASCII碼表示的結果。
調整方法:若AL中低4位小于或等于9,僅AL中高4位清0,AF→CF。若AL中低4位大于9或標志AF=1(進位),則AL+6→AL,AH+1→AH,1→AF,AF→CF,AL中高4位清0。
AAA指令一般緊跟在ADD或ADC指令之后使用,影響標志位為AF,CF。其它標志位無定義。
例 3.35
MOV AX,0036H
ADD,AL,35H
AAA;AX=0101H
(2) 格式:AAS
功能:將存放在AL中的二進制差數(shù),調整為ASCII碼表示形式
調整方法:若AL中低4位小于等于9,僅AL中高4位清0,AF→CF。若AL中低4位大于9或標志AF=1,則AL-6→AL,AH-1→AH,1→AF,AF→CF,AL中高4位清0。
AAS指令一般緊跟在SUB,SBB指令之后使用,影響標志位為AF,CF。其它標志位無定義。
例 3.36
MOV AX,0132H
SUB AL,35H
AAS;AX=0007H
(3) 格式:AAM
功能:將存放在AL中的二進制積數(shù),調整為ASCII碼表示形式。
調整方法:AL/10商→AH,余數(shù)→AL
AAM指令一般緊跟在MUL指令之后使用,影響標志位為SF,ZF,PF。其它標志位無定義。
例 3.37
MOV AL,07H
MOV BL,09H
MUL BL;AX=003FH
AAM;AX=0603H
(4) 格式:AAD
功能:將AX中兩位非壓縮BCD碼(一個字節(jié)存放一位BCD碼),轉換為二進制數(shù)的表示形式。
調整方法:AH10+AL→AL0→AH
AAD指令用于二進制除法DIV操作之前,影響的標志位為SF,ZF,PF。其它標志位無定義。
例 3.38
MOV AX,0605H
MOV BL,09H
AAD;AX=0041H
DIV BL;AX=0207H
使用該類指令應注意,加法、減法和乘法調整指令都是緊跟在算術運算指令之后,將二進制的運算結果調整為非壓縮BCD碼表示形式,而除法調整指令必須放在除法指令之前進行,以避免除法出現(xiàn)錯誤的結果。
使用算術運算類指令應注意:
·如果沒有特別規(guī)定,參與運算的兩個操作數(shù)數(shù)據(jù)類型必須一致,且只允許一個為存儲器操作數(shù);
·如果參與運算的操作數(shù)只有一個,且為存儲器操作數(shù),必須使用PTR偽指令說明數(shù)據(jù)類型;
·操作數(shù)不允許為段寄存器。
·目的操作數(shù)不允許為立即數(shù);
·如果是存儲器尋址,則存儲器各種尋址方式均可使用。
3.3.3邏輯運算指令
一、邏輯指令
1邏輯與指令
格式:AND DEST,SRC
功能:目的操作數(shù)和源操作數(shù)按位進行邏輯與運算,結果存目的操作數(shù)中。源操作數(shù)可以是通用寄存器、存儲器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲器操作數(shù)。
例 3.39
AND AL,BL
AND EBX,ECX
AND [DI],1101H
AND指令常用于將操作數(shù)中某位清0(稱屏蔽),只須將要清0的位與0,其它不變的位與1即可。
例 3.40  AND AL,0FH;將AL中高4位清0,低4位保持不變。
AND指令影響標志位為SF,ZF,PF,并且使OF=CF=0。
2邏輯或指令
格式:OR DEST,SRC
功能:目的操作數(shù)和源操作數(shù)按位進行邏輯或運算,結果存目的操作數(shù)中。源操作數(shù)可以是通用寄存器、存儲器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲器操作數(shù)。
例 3.41
OR AX,BX
OR ECX,[EAX]
OR指令常用于將操作數(shù)中某位置1,只須將要置1的位或1,其它不改變的位或0即可。
例 3.42  OR AL,80H;將AL中最高位置1。
OR指令影響標志位為SF,ZF,PF。并且使OF=CF=0。
3邏輯異或指令
格式:XOR DEST,SRC
功能:目的操作數(shù)和源操作數(shù)按位進行邏輯異或運算,結果送目的操作數(shù)。源操作數(shù)可以是通用寄存器、存儲器或立即數(shù)。目的操作數(shù)可以是通用寄存器或存儲器操作數(shù)。
例 3.43
XOR AX,BX
XOR [BX],1010H
XOR指令常用于將操作數(shù)中某些位取反,只須將要取反的位異或1,其它不改變的位異或0即可。
例 3.44  XOR AL,OFH;將AL中低4位取反,高4位保持不變。
XOR指令影響標志位為SF,ZF,PF,并且使OF=CF=0。
4邏輯非指令
格式:NOT DEST
功能:對目的操作數(shù)按位取反,結果回送目的操作數(shù)。目的操作數(shù)可以為通用寄存器或存儲器。
例 3.45
NOT EAX
NOT BYTE PTR [BX]
NOT指令對標志位無影響。
5測試指令
格式:TEST DEST,SRC
功能:目的操作數(shù)和源操作數(shù)按位進行邏輯與操作,結果不回送目的操作數(shù)。源操作數(shù)可以為通用寄存器、存儲器或立即數(shù)。目的操作數(shù)可以為通用寄存器或存儲器操作數(shù)。
例 3.46
TEST DWORD PTR [BX],80000000H
TEST AL,CL
TEST指令常用于測試操作數(shù)中某位是否為1,而且不會影響目的操作數(shù)。如果測試某位的狀態(tài),對某位進行邏輯與1的運算,其它位邏輯與0,然后判斷標志位。運算結果為0,ZF=1,表示被測試位為0;否則ZF=0,表示被測試位為1。
例 3.47  TEST AL,80H;測試AL中最高位
JNZ NEXT;如果最高位為1,轉到標志NEXT處。
TEST指令影響標志位為SF,ZF,PF,并且使OF=CF=0。
二、移位指令
移位指令對操作數(shù)按某種方式左移或右移,移位位數(shù)可以由立即數(shù)直接給出,或由CL間接給出。移位指令分一般移位指令和循環(huán)移位指令。
1一般移位指令
(1) 算術/邏輯左移指令。
格式:SAL DEST,OPRD
SHL DEST,OPRD
功能:按照操作數(shù)OPRD規(guī)定的移位位數(shù),對目的操作數(shù)進行左移操作,最高位移入CF中。每移動一位,右邊補一位0。如圖312(a)所示。目的操作數(shù)可以為通用寄存器或存儲器操作數(shù)。
SAL,SHL指令影響標志位OF,SF,ZF,PF,CF。
圖 3.12  移位指令示意圖
例 3.48
SHL BYTE PTR [DI],2
SAL BX,CL
(2) 算術右移指令。
格式:SAR DEST,OPRD
功能:按照操作數(shù)OPRD規(guī)定的移位次數(shù),對目的操作數(shù)進行右移操作,最低位移至CF中,最高位(即符號位)保持不變。如圖312(b)所示。目的操作數(shù)可以為通用寄存器或存儲器操作數(shù)。
SAR指令影響標志位OF,SF,ZF,PF,CF。
例 3.49
SAR AL,5
SAR WORD PTR /[ECX/],CL
(3) 邏輯右移指令。
格式:SHR DEST,SRC
功能:按照操作數(shù)OPRD規(guī)定的移位位數(shù),對目的操作數(shù)進行右移操作,最低位移至CF中。每移動一位,左邊補一位0。如圖312(c)所示,目的操作數(shù)可以為通用寄存器或存儲器操作數(shù)。
SHR指令影響標志位OF,SF,ZF,PF,CF。
例 3.50
SHR BYTE PTR [SI],3
SHR EDX,CL
算術/邏輯左移,只要結果未超出目的操作數(shù)所能表達的范圍,每左移一次相當于原數(shù)乘2。算術右移只要無溢出,每右移一次相當于原數(shù)除以2。
2循環(huán)移位指令
格式:ROL DEST,OPRD
ROR DEST,OPRD
RCL DEST,OPRD
RCR DEST,OPRD
功能:循環(huán)左移指令ROL,見圖313(a)所示,目的操作數(shù)左移,每移位一次,其最高位移入最低位,同時最高位也移入進位標志CF。循環(huán)右移指令 ROR見圖313(b)所示,目的操作數(shù)右移,每移位一次,其最低位移入最高位,同時最低位也移入進位標志CF。
帶進位循環(huán)左移指令RCL,見圖313(c)所示,目的操作數(shù)左移,每移動一次,其最高位移入進位標志CF,CF移入最低位。帶進位循環(huán)右移指令RCR,見圖313(d)所示,目的操作數(shù)右移,每移動一次,其最低位移入進位標志CF,CF移入最高位。
圖 3.13  循環(huán)移位指令
目的操作數(shù)可以為通用寄存器或存儲器操作數(shù)。循環(huán)移位指令影響標志位CF,OF。其它標志位無定義。
例 3.51
ROL AL,CL
ROR BX,5
RCL ECX,3
RCR BYTE PTR [SI],CL
例 3.52  將一個2位數(shù)壓縮的BCD碼轉換成二進制數(shù)。
·MODEL SMALL
·DATA
BCD DB 01011001B
BIN DB?
CODE
·START UP
MOV AL,BCD
MOV BL,AL
AND BL,0FH
AND AL,0F0H
MOV CL,4
ROR AL,CL
MOV BH,0AH
MUL BH
ADD AL,BL
MOV BIN,AL
·EXIT
END
3雙精度移位指令
格式:SHLD DEST,SRC,OPRD
SHRD DEST,SRC,OPRD
功能:對于由目的操作數(shù)DEST和源操作數(shù)SRC構成的雙精度數(shù),按照操作數(shù)OPRD給出的移位位數(shù),進行移位。SHLD是對目的操作數(shù)進行左移,如 圖314(a)所示,SHRD是對目的操作數(shù)進行右移,如圖314(b)所示。先移出位送標志位CF,另一端空出位由SRC移入DEST中,而SRC 內容保持不變。目的操作數(shù)可以是16位或32位通用寄存器或存儲器操作數(shù)。源操作數(shù)SRC允許為16位或32位通用寄存器。操作數(shù)OPRD可以為立即數(shù)或 CL。目的操作數(shù)和源操作數(shù)SRC數(shù)據(jù)類型必須一致。
圖 3.14  雙精度移位指令
SHLD,SHRD指令常用于位串的快速移位、嵌入和刪除等操作,影響標志位為SF,ZF,PF,CF,其它標志位無定義。
三、位操作指令
位操作指令包括位測試和位掃描指令,可以直接對一個二進制位進行測試,設置和掃描。
1位測試和設置指令
格式:BT DEST,SRC
BTC DEST,SRC
BTR DEST,SRC
BTS DEST,SRC
功能:按照源操作指定的位號,測試目的操作數(shù),當指令執(zhí)行時,被測試位的狀態(tài)被復制到進位標志CF。
BT將SRC指定的DEST中一位的數(shù)值復制到CF。BTC將SRC指定的DEST中一位的數(shù)值復制到CF,且將DEST中該位取反。BTR將SRC 指定的DEST中一位的數(shù)值復制到CF,且將DEST中該位復位。BTS將SRC指定的DEST中一位的數(shù)值復制到CF,且將DEST中該位置位。
目的操作數(shù)為16位或32位通用寄存器或存儲器,源操作數(shù)為16位或32位通用寄存器,以及8位立即數(shù),當源操作數(shù)為通用寄存器時,必須同目的操作數(shù)類型一致。源操作數(shù)SRC以兩種方式給出目的操作數(shù)的位號,即
· SRC為8位立即數(shù),以二進制形式直接給出要操作的位號;
· SRC為通用寄存器,如果DEST為通用寄存器,則SRC中二進制值直接給出要操作的位號。如果DEST為存儲器操作數(shù),通用寄存器SRC為帶符號整數(shù), SRC的值除以DEST的長度所得到的商作為DEST的相對偏移量,余數(shù)直接作為要操作的位號。DEST的有效地址為DEST給出的偏移地址和DEST相 對偏移量之和。
BT,BTC,BTR,BTS指令影響CF標志位,其它標志位無定義。
例 3.53
MOV AX,1234H
MOV ECX,5
BT AX,CX      ??;CF=1AX=1234H
BTC AX,5      ?。籆F=1;AX=1214H
BTS AX,CX;      ;CF=0AX=1234H
BTR EAX,ECX      ;CF=1EAX=00001214H
例 3.54
·MODEL SMALL
·586
·DATA
DATA1 DW 1234H,5678H
·CODE
·START UP
BTC DATA1,3;CF=0(DATA1)=123CH
MOV CX,20
BTR DATA1,CX;CF=1[DATA+2]=5668H
·EXIT
END
2位掃描指令
格式:BSFDEST,SRC
BSRDEST,SRC
功能:BSF從低位開始掃描源操作數(shù),若所有位都是0,則ZF=0,否則ZF=1。并且將第一個出現(xiàn)1的位號存入目的操作數(shù)。BSR從高位開始掃描源操作數(shù),若所有位都是0,則ZF=0,否則ZF=1。并且將第一個出現(xiàn)1的位號存入目的操作數(shù)。
源操作數(shù)可以為16位32位通用寄存器或存儲器。目的操作數(shù)為16位或32位通用寄存器。源操作數(shù)和目的操作數(shù)類型必須一致。
BSF,BSR指令影響ZF標志位,其它標志位無定義。
例 3.55
MOV EBX,0F333EE00H
BSR EAX,EBX;ZF=1EAX=0000001FH=31
BSF EDX,EBX;ZF=1EDX=00000009H
3進位標志指令
(1) 格式:CLC。功能:清除進位標志。
(2) 格式:STC。功能:設置進位標志。
(3) 格式:CMC。功能:進位標志取反。
4條件設置字節(jié)指令
條件設置指令用于根據(jù)條件設置某一狀態(tài)字節(jié)或標志字節(jié),見表33。
格式:SETcondDEST
功能:測試條件(cond)若為真,則將目的操作數(shù)置01H,否則置00H。目的操作數(shù)允許為8位通用寄存器或8位存儲器操作數(shù)。
條件cond與條件轉移指令中的條件相同,共分三類。
(1) 以標志位狀態(tài)為條件可以測試的標志位為ZF,SF,OF,CF,PF。
(2) 以兩個無符號數(shù)比較為條件條件為高于、高于等于、低于、低于等于。
(3) 以兩個帶符號數(shù)比較為條件條件為大于、大于等于、小于、小于等于。
SET指令不影響標志位。
使用邏輯運算類指令應注意:
· 如果沒有特別規(guī)定,參與運算的兩個操作數(shù)類型必須一致,且只允許一個為存儲器操作數(shù);
· 如果參與運算的操作數(shù)只有一個,且為存儲器操作數(shù),必須使用PTR偽指令說明其數(shù)據(jù)類型;
· 操作數(shù)不允許為段寄存器;
· 目的操作數(shù)不允許為立即數(shù);
· 如果是存儲器尋址,則前面介紹的各種存儲器尋址方式均可使用。
表 3.3  條件設置字節(jié)指令
3.3.4控制轉移類指令
計算機執(zhí)行程序一般是順序地逐條執(zhí)行指令。但經(jīng)常須要根據(jù)不同條件做不同的處理,有時需要跳過幾條指令,有時需要重復執(zhí)行某段程序,或者轉移到另一個程序段去執(zhí)行。用于控制程序流程的指令包括轉移、循環(huán)、過程調用和中斷調用。
一、轉移指令
1無條件轉移指令
格式:JMP TARGET
功能:使程序無條件地轉移到指令規(guī)定的目的地址TARGET去執(zhí)行指令。轉移分為短轉移、段內轉移(近程轉移)和段間轉移(遠程轉移)。
(1) 段內直接轉移:
格式:JMP SHORT TARGET;短轉移
JMP NEAR PTR TARGET;近程轉移
功能:采用相對尋址將當前IP值(即JMP指令下一條指令的地址)與JMP指令中給出的偏移量之和送IP中。段內短轉移(SHORT)指令偏移量為8 位,允許轉移偏移值的范圍為-128~+127。段內近程轉移(NEAR)指令在16位指令模式下,偏移量為16位,允許轉移偏移值范圍為-215~+ 215-1。在32位指令模式下,偏移值范圍為-231~+231-1。
例 3.56
JMP NEXT
NEXT:MOV AL,BL
本例為無條件轉移到本段內,標號為NEXT的地址去執(zhí)行指令,匯編程序可以確定目的地址與JMP指令的距離。
(2) 段內間接轉移:
格式:JMP REG
JMP NEAR PTR [REG]
功能:段內間接轉移,其中JMP REG指令地址在通用寄存器中,將其內容直接送IP實現(xiàn)程序轉移。JMP NEAR PTR [REG]指令地址在存儲器中,默認段寄存器根據(jù)參與尋址的通用寄存器來確定,將指定存儲單元的字取出直接送IP實現(xiàn)程序轉移。在16位指令模式,轉移偏 移值范圍為
。在32位指令模式,轉移偏移值范圍為
。
例 3.57 設DS=1000HEBX=00002000H。
JMP BX         ??;將2000H送IP
JMP NEAR PTR [BX]     ;將地址1000∶2000單元存放的一個字送IP
JMP NEAR PTR [EBX]    ;將段選擇符為1000H,偏移地址為00002000H單元存放的雙字送EIP。
(3) 段間直接轉移:
格式:JMP FAR PTR TARGET
功能:段間直接轉移,F(xiàn)AR PTR說明標號TARGET具有遠程屬性。將指令中由TARGET指定的段值送CS,偏移地址送IP。
例 3.58 JMP FAR PTR NEXT。
在16位指令模式下,段基地送CS,偏移地址為16位,轉移偏移值范圍
;在32位指令模式下,代碼段選擇符送CS,偏移地址為32位,轉移偏移值范圍為
。
(4) 段間間接轉移:
格式:JMP FAR PTR [Reg]
功能:段間間接轉移,由FAR PTR [Reg]指定的存儲器操作數(shù)作為轉移地址。
在16位指令模式下,存儲器操作數(shù)為32位,包括16位段基址和16位偏移地址。
例 3.59
JMP FAR PTR [BX]     ??;數(shù)據(jù)段雙字存儲單元低字內容送IP
;數(shù)據(jù)段雙字存儲單元高字內容送CS
在32位指令模式下,存儲器操作數(shù)包括16位選擇符。
例 3.60  JMP FAR PTR [EAX]
指令中包含指向目標地址指針的門描述符或TSS描述符的指針,其所指的存儲器操作數(shù)中僅選擇符部分有效,指示調用門、任務門或TSS描述符起作用,而偏移部分不起作用。
2條件轉移指令
該類指令是根據(jù)上一條指令對標志寄存器中標志位的影響來決定程序執(zhí)行的流程,若滿足指令規(guī)定的條件,則程序轉移;否則程序順序執(zhí)行。
條件轉移指令的轉移范圍為段內短轉移或段內近程轉移,不允許段間轉移。段內短轉移(short)的轉移偏移值范圍為-128~+127。段內近程轉移,在16位指令模式下轉移偏移值范圍為
,在32位指令模式下轉移偏移值范圍為
。
條件轉移指令包括四類:單標志位條件轉移;無符號數(shù)比較條件轉移;帶符號數(shù)比較條件轉移;測試CX條件轉移。
格式:Jcc TARGET
功能:若測試條件‘CC’為真,則轉移到目標地址TARGET處執(zhí)行程序。否則順序執(zhí)行。
(1) 單標志位條件轉移指令,見表34。
例 3.61 JZ NEXT;若標志ZF=1則轉移到標號NEXT處執(zhí)行。
(2) 無符號數(shù)比較條件轉移,見表35。
例 3.62 JA NEXT;無符號數(shù)A與B比較,若A>B則轉移到標號NEXT處執(zhí)行程序
表 3.4 單標志位條件轉移指令
表 3.5 無符號數(shù)比較條件轉移指令
表 3.6 帶符號數(shù)比較條件轉移指令
例 3.63  JG NEXT;帶符號數(shù)A與B比較,若A>B則轉移到標號NEXT。
(4) 測試CX條件轉移,見表37。
表 3.7 測試CX條件轉移指令
例 3.64 JCXZ TARGET;CX=0轉移到標號TARGET處。
JECXZ TARGET;ECX=0轉移到標號TARGET處。
條件轉移指令一般緊跟在CMP或TEST指令之后,判斷執(zhí)行CMP或TEST指令對標志位的影響來決定是否轉移。
例 3.65 符號函數(shù)
假設x為某值且存放在寄存器AL中,試編程將求出的函數(shù)值f(x)存放在AH中。
·MODEL TINY
·CODE
·STARTUP
CMPAL,0
JGE BIG
MOV AL,0FFH
JMP DONE
BIG: JE DONE
MOV AL,1
DONE:MOV AH,AL
·EXIT
END
例 3.66 編程實現(xiàn)把BX寄存器內的二進制數(shù)用十六進制數(shù)的形式在屏幕上顯示出來。
·MODEL TINY
·CODE
·STARTUP
MOV CH,4
AGAIN: MOV CL,4
ROL BX,CL
MOV AL,BL
ANDAL,0FH
OR AL,30H
CMP AL,3AH
JB NEXT
ADD AL,07H
NEXT: MOV DL,AL;DL←要顯示的ASCII碼
MOV AH,2;顯示
INT 21H
DECCH
JNZ AGAIN
·EXIT
END
二、循環(huán)控制指令
這類指令用(E)CX計數(shù)器中的內容控制循環(huán)次數(shù),先將循環(huán)計數(shù)值存放在(E)CX中,每循環(huán)一次(E)CX內容減1,直到(E)CX為0時循環(huán)結束。
格式:LOOPcc TARGET
功能:將(E)CX內容減1,不影響標志位,若(E)CX不等于0,且測試條件‘CC’成立,則轉移到目標地址TARGET處執(zhí)行程序。轉移范圍為-128~+127。如表38所示。
表3.8 循環(huán)控制指令
例 3.67 計算
·MODEL TINY
·CODE
·STARTUP
XOR EAX,EAX
MOV EDX,1
MOV ECX,1000
SUM:  ADD EAX,EDX
INC EDX
LOOPD SUM
·EXIT
END
例 3.68 找出以ARRAY為首地址的100個字數(shù)組中的第一個非0項,送AX寄存器中。
·MODELSMALL
·DATA
ARRAYDW 0,0,0,0,1010H,…;(100個字)
·CODE
·STARTUP
MOV CX,64H
LEA BX,ARRAY
MOV SI,0FFFEH
ZERO: INC SI
INC SI
CMP WORD PTR [BX+SI],0
LOOPZ ZERO
MOV AX,[BX+SI]
·EXIT
END
關于過程調用和返回指令將在子程序一節(jié)中介紹。
3.3.5串操作指令
80x86提供處理字符串的操作。串指連續(xù)存放在存儲器中的一些數(shù)據(jù)字節(jié)、字或雙字。串操作允許程序對連續(xù)存放大的數(shù)據(jù)塊進行操作。
串操作通常以DS:(E)SI來尋址源串,以ES:(E)DI來尋址目的串,對于源串允許段超越。(E)SI或(E)DI這兩個地址指針在每次串操作 后,都自動進行修改,以指向串中下一個串元素。地址指針修改是增量還是減量由方向標志來規(guī)定。當DF=0,(E)SI及(E)DI的修改為增量;當DF= 1,(E)SI及(E)DI的修改為減量。根據(jù)串元素類型不同,地址指針增減量也不同,在串操作時,字節(jié)類型SI,DI加、減1;字類型SI,DI加、減 2;雙字類型ESI,EDI加、減4。如果需要連續(xù)進行串操作,通常加重復前綴。重復前綴可以和任何串操作指令組合,形成復合指令,見表39。
一、重復前綴指令
表 3.9 重復前綴指令
二、方向標志指令
格式:CLD/STD
功能:CLD為清除方向標志,即將DF置‘0’。STD為設置方向標志,即將DF置‘1’。
三、串傳送指令
基本格式:[REP]MOVS DESTS, SRCS
[REP] MOVSB/MOVSW/MOVSD
功能:將DS:(E)SI規(guī)定的源串元素復制到ES:(E)DI規(guī)定的目的串單元中,見表310。
表 3.10 MOVS指令
該指令對標志位無影響。
如果加重復前綴REP,則可以實現(xiàn)連續(xù)存放的數(shù)據(jù)塊的傳送,直到(E)CX=0為止。
在16位指令模式下,使用SI,DI,CX寄存器;在32位指令模式下,使用ESI,EDI,ECX寄存器。
例 3.69
·MODEL SMALL
·DATA
SRC  DB 1,2,3,…(100個字節(jié))
DEST DB 100DUP(?)
·CODE
·STARTUP
MOV AX,@DATA
MOV ES,AX
MOV CX,100
LEA SI,SRC
LEA DI,DEST
CLD
REP MOVSB
·EXIT
END
該程序將起始地址為SRC的100個字節(jié)內容傳送到起始地址為DEST的存儲單元。
四、串比較指令
基本格式:[REPE/Z] [REPNZ/NE] CMPS DESTS, SRCS
[REPE/Z] [REPNZ/NE] CMPSB/CMPSW/CMPSD
功能:由DS:(E)SI規(guī)定的源串元素減去ES:(E)DI指出的目的串元素,結果不回送,僅影響標志位CF,AF,PF,OF,ZF,SF。當源 串元素與目的串元素值相同時,ZF=1;否則ZF=0。每執(zhí)行一次串比較指令,根據(jù)DF的值和串元素數(shù)據(jù)類型自動修改(E)SI和(E)DI。
在串比較指令前加重復前綴REPE/Z,則表示重復比較兩個字符串,若兩個字符串的元素相同則比較到(E)CX=0為止,否則結束比較。在串比較指令 前加重復前綴REPNE/NZ,則表示若兩個字符串元素不相同時,重復比較直到(E)CX=0為止,否則結束比較。
例 3.70 編程實現(xiàn)兩個串元素比較,如相同則將全“1”送SUT單元,否則全“0”送SUT單元。
·MODEL SMALL
·DATA
DEST DB ‘A B C D E F G H’
SRC  DB ‘A B C E F F F E’
SUT  DB?
·CODE
·STARTUP
MOV AX,@DATA
MOV ES,AX
MOV CX,8
LEA SI,DEST
LEA DI,SRC
CLD
REPE CMPSB
JZ EQUL;ZF=1;CX=0
MOV BH,0;CX≠0,ZF=0
JMP DONE
EQUL: MOV BH,0FFH
DONE: MOV SUT,BH
·EXIT
END
五、串掃描指令
格式①: [REPE/Z] [REPNE/NZ] SCAS DESTS
格式②: [REPE/Z] [REPNE/NZ] SCASB/SCASW/SCASD
功能:由AL,AX或EAX的內容減去ES:(E)DI規(guī)定的目的串元素,結果不回送,僅影響標志位CF,AF,PF,SF,OF,ZF。當AL, AX或EAX的值與目的串元素值相同時,ZF=1;否則ZF=0。每執(zhí)行一次串掃描指令,根據(jù)DF的值和串元素數(shù)據(jù)類型自動修改(E)DI。
在串掃描指令前加重復前綴REPE/Z,則表示目的串元素值和累加器值相同時重復掃描,直到CX/ECX=0為止,否則結束掃描。若加重復前綴 REPNE/NZ,則表示當目的串元素值與累加器值不相等時,重復掃描直到CX/ECX=0時為止,否則結束掃描。
該指令影響標志位為CF,AF,PF,SF,OF,ZF。
例 3.71 在內存DEST開始的6個單元尋找字符‘C’,如找到將字符‘C’的地址送ADDR單元,否則0送ADDR單元。
·MODEL SMALL
·DATA
DEST DB ‘A B C D E F’
ADDR DW?;存“C”的地址,所以設置為字類型
·CODE
·STARTUP
MOV AX,@DATA
MOV ES,AX
MOV CX,6
LEA DI,DEST
MOV AL,‘C’
CLD
REPNE SCASB
JZ EQUL
MOV DI,0
JMP DONE
EQUL: DEC DI
DONE: MOV ADDR,DI
·EXIT
END
六、 串裝入指令
格式:LODS SRCS
LODSB/LODSW/LODSD
功能:將DS:SI/ESI所指的源串元素裝入累加器(AL,AX,EAX)中,每裝入一次都按照DF值以及串元素類型自動修改地址指針SI/ESI,該指令一般不須加重復前綴,并且不影響標志位。
七、 串存儲指令
格式:[REP] STOS DESTS
[REP] STOSB/STOSW/STOSD
功能:將累加器/[AL,AX,EAX/]中值存入ES:DI/EDI所指的目的串存儲單元中,每傳遞一次,都按DF值以及串元素類型自動修改地址指 針DI/EDI。若加重復前綴REP,則表示將累加器的值連續(xù)送目的串存儲單元,直到CX/ECX=0時為止。
該指令不影響標志位。
3.3.6輸入/輸出指令
一、 輸入指令
格式:IN DEST, SRC
功能:根據(jù)源操作數(shù)SRC給出的端口地址,將操作數(shù)從指定端口傳送到目的操作數(shù)DEST處,其中DEST為AL,AX或EAX,端口地址SRC可以直接形式給出8位端口地址,或由DX寄存器以間接形式給出。
例 3.72
IN AL,10H
IN AX,20H
IN EAX,30H
IN AL,DX
IN AX,DX
IN EAX,DX
二、 輸出指令
格式OUT DEST, SRC
功能:將源操作數(shù)SRC送到目的操作數(shù)DEST所指定的端口。其中源操作數(shù)SRC為AL,AX或EAX,目的操作數(shù)可以8位端口地址方式直接給出或以DX寄存器間接方式給出。
使用輸入、輸出指令應注意:
· 直接尋址方式端口地址為8位,共有0~255個端口地址;
· 間接尋址方式,只能用DX作為地址寄存器,尋址范圍為64K字節(jié);
· 每個I/O地址對應的端口的數(shù)據(jù)長度為8位,傳送8位數(shù)據(jù)占用一個端口地址,傳送16位數(shù)據(jù)占用2個端口地址,傳送32位數(shù)據(jù)占用4個端口地址。
三、 串輸入指令
格式:[REP] INS DESTS, DX
[REP] INSB/INSW/INSD
功能:根據(jù)DX給出的端口地址,從外設讀入數(shù)據(jù)送入以ES:DI/EDI為地址的目的串存儲單元中,每輸入一次,均根據(jù)DF的值和串元素類型自動修改 DI/EDI的值。若加重復前綴REP,則表示連續(xù)從外設輸入串元素存入目的串存儲單元中,直到CX/ECX=0為止。
例 3.73 從端口地址為1000H處取數(shù)存入內存BLOCK單元。
·MODEL SMALL
·DATA
BLOCKDB?
·CODE
·STARTUP
MOV AX,@DATA
MOV ES,AX
CLD
LEA DI,BLOCK
MOV DX,1000H
INS BLOCK,DX
·EXIT
END
四、串輸出指令
格式:[REP] OUTS DX,SRCS
[REP] OUTSB/OUTSW/OUTSD
功能:將DS:SI/ESI所指的源串元素,按照DX寄存器指定的端口地址送往外設,每輸出一次,均根據(jù)DF的值和串元素類型自動修改SI/ESI的值,若加重復前綴REP,則表示連續(xù)向外設輸出串元素,直到CX/ECX=0時為止。
例 3.74 將內存BLOCK為首地址的100個字符送往端口地址為2000H的外設。
·MODEL SMALL
·DATA
BLOCKDB ‘A,B,…’(100個字符)
·CODE
·STARTUP
CLD
LEA SI,BLOCK
MOV CX,100
MOV DX,2000H
REP OUTSB
·EXIT
END
在使用帶重復前綴的串輸入輸出指令時,必須考慮端口的數(shù)據(jù)準備或接收狀態(tài)。
所有輸入輸出指令均不影響標志位。
3.3.7處理器控制
一、 總線封鎖前綴
格式:LOCK指令
功能:LOCK為指令前綴,可以使LOCK引腳變成邏輯0,在LOCK引腳有效期間,禁止外部總線上的其它處理器存取帶有LOCK前綴指令的存儲器操作數(shù)。
可加LOCK前綴的指令:
(1) ADD/SUB/ADC/SBB/OR/XOR/AND Mem, Reg/imm;
(2) NOT/NEG/INC/NEC Mem;
(3) XCHG Reg, Mem或XCHG Mem, Reg;
(4) BT/BTS/BRT/BTC Mem, Reg/imm。
Mem為存儲器操作數(shù),Reg為通用寄存器,imm為立即數(shù)。
二、空操作
格式:NOP
功能:空操作,除使IP/EIP增1外,不做任何工作。該指令不影響標志位。
三、處理器等待指令
格式:WAIT
功能:檢查BUSY引腳狀態(tài),等待協(xié)處理器完成當前工作。
四、處理器暫停指令
格式:HLT
功能:暫停程序的執(zhí)行。當產(chǎn)生一個外部中斷或非屏蔽中斷時,才繼續(xù)執(zhí)行下一條指令。
3.3.8中斷指令與DOS功能調用
一、中斷指令
在實模式下,中斷矢量以4個字節(jié)存放在中斷矢量表中,中斷矢量表為1k字節(jié)(00000H~003FFH),中斷矢量表允許存放256個中斷矢量,每 個中斷矢量包含一個中斷服務程序地址(段值和16位偏移地址),中斷矢量地址指針由中斷類型碼乘以4得到。
在保護模式下,用中斷描述符表代替中斷矢量表,每個中斷由8個字節(jié)的中斷描述符來說明,中斷描述符表允許256個中斷描述符,每個中斷描述符包含一個中斷服務地址(段選擇符、32位偏移地址、訪問權限等)。中斷描述符地址指針由中斷類型碼乘以8得到。
中斷指令格式:INT n
功能:產(chǎn)生中斷類型碼為n的軟中斷,該指令包含中斷操作碼和中斷類型碼兩部分,中斷類型碼n為8位,取值范圍為0~255(00H~FFH)。
軟中斷執(zhí)行過程:
· 將標志寄存器FLAGS(或EFLAGS)壓入堆棧;
· 清除TF和IF標志位;
· CS,IP/EIP壓入堆棧;
· 實模式下,n×4獲取中斷矢量表地址指針;保護模式下,n×8獲取中斷描述符表地址指針;
· 根據(jù)地址指針,從中斷矢量表或中斷描述符表中取出中斷服務程序地址送IP/EIP和CS中,控制程序轉移去執(zhí)行中斷服務程序。
中斷返回指令格式:IRET/IRETD
功能:該指令實現(xiàn)在中斷服務程序結束后,返回到主程序中斷斷點處,繼續(xù)執(zhí)行主程序。
中斷返回執(zhí)行過程:
· IRET指令彈出堆棧中數(shù)據(jù)送IP,CS,F(xiàn)LAGS;
· IRETD指令彈出堆棧中數(shù)據(jù)送EIP,CS,EFLAGS。
其它中斷類指令如表311所示。
表 3.11 中斷類指令
二、DOS功能調用
系統(tǒng)功能調用是MS—DOS為程序員編寫匯編語言源程序提供的一組子程序,包括設備管理、文件管理和目錄管理等。
DOS規(guī)定使用軟中斷指令INT 21H作為進入各功能子程序的總入口,再為每個功能調用規(guī)定一個功能號,引用功能號即可進入相應的子程序入口。DOS系統(tǒng)功能調用的使用方法歸納如下:
(1) 傳送入口參數(shù)到指定的寄存器中;
(2) 把要調用功能的功能號送入AH寄存器中;
(3) 用INT 21H指令轉入子程序入口;
(4) 相應的子程序運行結束后,可以按照規(guī)定取得出口參數(shù)。
常用系統(tǒng)功能調用簡介。
1鍵盤輸入單字符
這是1號系統(tǒng)功能調用,其調用格式為
MOV AH,1
INT 21H
該功能調用無入口參數(shù)。其功能為系統(tǒng)等待鍵盤輸入,如是Ctrol-Break鍵則退出;否則將鍵入字符的ASCII碼送入AL寄存器中,并且通過顯示器顯示該字符。
2鍵盤輸入字符串
這是0AH號系統(tǒng)功能調用,其功能為將鍵盤輸入的字符串寫入內存單元中。因此,首先在內存中定義一個緩沖區(qū),緩沖區(qū)第一個字節(jié)存放規(guī)定字符串的最大字 節(jié)數(shù),第二個字節(jié)由系統(tǒng)送入實際鍵入的字符數(shù),從第三個字節(jié)開始用于存放鍵入的字符串,最后通過鍵入回車鍵來表示字符串的結束。如果實際鍵入的字符數(shù)未達 到最大規(guī)定數(shù),其緩沖區(qū)的空余區(qū)間填0;如果實際鍵入數(shù)超過緩沖區(qū)的容量,則超出的字符自動丟失,而且響鈴警告。注意,回車鍵值也存于緩沖區(qū)中。
例 3.75 使用格式舉例。
·MODEL SMALL
·DATA
BUF  DB 20
DB?
DB 20 DUP(?)
·CODE
·STARTUP
MOV DX,OFFSET BUF
MOV AH,0AH
INT 21H
·EXIT
END
該程序在BUF為首地址的緩沖區(qū)定義了20個字符串字節(jié)的緩沖區(qū),并且將緩沖區(qū)首地址送入DX中,調用0AH號子程序,系統(tǒng)等待用戶鍵入字符串,每鍵 入一個字符,其相應的ASCII碼將被寫入緩沖區(qū)中,直到鍵入回車鍵,由系統(tǒng)輸入實際鍵入字符數(shù),送入緩沖區(qū)第二個字節(jié)中。
3輸出單字符
這是2號系統(tǒng)功能調用,其使用格式為:
MOV DL,‘A’
MOV AH,2
INT 21H
執(zhí)行2號系統(tǒng)功能調用,將置入DL寄存器中的字符(以ASCII碼形式表示)通過顯示器顯示出來(或從打印機輸出)。
4輸出字符串
這是9號系統(tǒng)功能調用,其功能是將指定的內存緩沖區(qū)中的字符串從顯示器顯示輸出(或從打印機輸出),緩沖區(qū)中的字符串以字符‘$’作為結束標志。
例 3.76使用格式舉例。
·MODEL SMALL
·DATA
BUF DB ‘Thank you $’
·CODE
·STARTUP
MOV DX,OFFSET BUF
MOV AH,9
INT 21H
·EXIT
END
5返回操作系統(tǒng)
這是4CH號系統(tǒng)功能調用,使用格式為
MOV AH,4CH
INT 21H
在用戶程序結束處插入此調用,則返回到DOS操作系統(tǒng),顯示器顯示系統(tǒng)提示符。
習題與思考題
1數(shù)據(jù)尋址方式有哪幾種?
216位指令模式下和32位指令模式下的存儲器尋址方式各有哪幾種尋址方式?并比較它們相似與不同之處。
3程序地址尋址方式有哪幾種?
4什么是堆棧地址尋址方式?
5指令編碼格式是由哪幾部分組成的?各部分的含義是什么?
6 80x86的指令格式由哪幾部分組成?
7 80x86指令系統(tǒng)按其功能可分為幾部分?
8數(shù)據(jù)傳送指令包括哪些類型?
9堆棧的含義是什么?80x86所用的堆棧有什么特點?
10堆棧操作指令有哪幾種?
11 XLAT指令在使用時有哪些規(guī)定?
12符號擴展指令在什么情況下使用?
13十進制算術運算調整指令在什么情況下使用?它們都是跟在哪些指令的后面?
14哪些指令采用隱含尋址?
15使用算術運算類指令應注意哪些問題?
16邏輯運算指令有幾種?
17測試指令和比較指令在使用時有什么不同?
18算術移位指令和邏輯移位指令有什么不同?
19控制轉移類指令的作用是什么?有哪幾種?
20什么叫串?串操作指令有哪些?串前綴在什么情況下使用?
21輸入/輸出指令起什么作用?尋址方式有哪些?
22設DS=2000H,SS=3000H,BP=0200H,SI=4000H,BUF=1000H,EAX=00001000H,EBX= 00002000H,假設按16位實模式操作,確定下列每條指令訪問內存的物理地址,并且指出源操作數(shù)及目的操作數(shù)的尋址方式。
(1) MOV AL,[1234H](2) MOV EDX,[BX]
(3) MOV CL,[BX+100H](4) MOV [SI],EBX
(5) MOV AH,BUF[BX+SI](6) MOV EAX,[BP+1234H]
(7) MOV [EAX+EBX],DH
23試指出下列指令中的錯誤。
(1) MOV [BX],[SI](2) MOV AH,DX
(3) INC [BX](4) MOV DS,SS
(5) XCHG AX,2000H(6) MOV AX,[BX+DX]
(7) XCHG [SP],ES(8) ADD [AX],BX
(9) MOV AX,DI+SI(10) INAL,BX
24指出下列算術邏輯指令執(zhí)行后標志CF,ZF,SF,PF,OF和AF的狀態(tài)。
MOV AL,80H
DEC AL
ADD AL,10H
SUB AL,10H
MOV AL,3AH
AND AL,0F0H
OR AL,0F0H
XOR AL,0F0H
25使AX寄存器清0有多種方式,試寫出這多條指令。
26寫出把首地址為BUF的字節(jié)緩沖區(qū)中第5個字節(jié)數(shù)送AL寄存器的指令,要求使用以下幾種尋址方式:
(1) 寄存器間接尋址;
(2) 寄存器相對尋址;
(3) 基址變址尋址。
27試分別使用數(shù)據(jù)傳送指令、交換指令和堆棧操作指令,實現(xiàn)將首地址為BLOCK的內存單元中兩個數(shù)據(jù)字交換。BLOCK變量定義如下:
BLOCK DW 10H,20H
28設一個字節(jié)數(shù)據(jù)X存放在AL寄存器中,試說明下列程序的功能。
XOR AH,AH
SAL AX,1
MOV BX,AX
MOV CL,2
SAL AX,CL
ADD AX,BX
29試編程實現(xiàn):
(1) AL寄存器的低4位清0;
(2) BL寄存器的低4位置1;
(3) CL寄存器的低4位取反;
(4) 測試DL寄存器的最低2位是否為0,若是將0送入AL寄存器;否則將1送AL寄存器。
30試編程統(tǒng)計在AX寄存器中有多少個1,并將結果送DL寄存器中。
31試編程統(tǒng)計在內存BLOCK單元開始按字節(jié)存放的100個帶符號數(shù)中有多少負數(shù),并將結果存放在DL寄存器中。
================================================================
80X86寄存器介紹
32位CPU所含有的寄存器有:
4個數(shù)據(jù)寄存器(EAX、EBX、ECX和EDX)
2個變址和指針寄存器(ESI和EDI) 2個指針寄存器(ESP和EBP)
6個段寄存器(ES、CS、SS、DS、FS和GS)
1個指令指針寄存器(EIP) 1個標志寄存器(EFlags)
1、數(shù)據(jù)寄存器
數(shù)據(jù)寄存器主要用來保存操作數(shù)和運算結果等信息,從而節(jié)省讀取操作數(shù)所需占用總線和訪問存儲器的時間。
32位CPU有4個32位的通用寄存器EAX、EBX、ECX和EDX。對低16位數(shù)據(jù)的存取,不會影響高16位的數(shù)據(jù)。這些
低16位寄存器分別命名為:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。
4個16位寄存器又可分割成8個獨立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每個寄
存器都有自己的名稱,可獨立存取。程序員可利用數(shù)據(jù)寄存器的這種“可分可合”的特性,靈活地處理字/字
節(jié)的信息。
AX和AL通常稱為累加器(Accumulator):可用于乘、除、輸入/輸出等操作(在乘除指令中指定用來存放操作數(shù))
BX稱為基地址寄存器(Base Register):在計算存儲器地址時,可作為基址寄存器使用。
CX稱為計數(shù)寄存器(Count Register):用來保存計數(shù)值,如在移位指令、循環(huán)指令和串處理指令中用作隱含的計數(shù)器(當移多位時,要用CL來指明移位的位數(shù))。DX在作雙字長運算時,可把DX和AX組合在一起存放一個雙字長數(shù),DX用來存放高16位數(shù)據(jù)。此外,對某些I/O操作,DX可用來存放I/O的端口地址。
DX稱為數(shù)據(jù)寄存器(Data Register)。在進行乘、除運算時,它可作為默認的操作數(shù)參與運算,也可用于存放I/O的端口地址。
在16位CPU中,AX、BX、CX和DX不能作為基址和變址寄存器來存放存儲單元的地址,但在32位CPU中,其32位
寄存器EAX、EBX、ECX和EDX不僅可傳送數(shù)據(jù)、暫存數(shù)據(jù)保存算術邏輯運算結果,而且也可作為指針寄存器,
所以,這些32位寄存器更具有通用性。
2、變址寄存器
32位CPU有2個32位通用寄存器ESI和EDI。其低16位對應先前CPU中的SI和DI,對低16位數(shù)據(jù)的存取,不影響
高16位的數(shù)據(jù)。
寄存器ESI、EDI、SI和DI稱為變址寄存器(Index Register),它們主要用于存放存儲單元在段內的偏移量,
用它們可實現(xiàn)多種存儲器操作數(shù)的尋址方式,為以不同的地址形式訪問存儲單元提供方便。
變址寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲算術邏輯運算的操作數(shù)和運算結果。
它們可作一般的存儲器指針使用。在字符串操作指令的執(zhí)行過程中,對它們有特定的要求,而且還具有特
殊的功能。
3、指針寄存器
32位CPU有2個32位通用寄存器EBP和ESP。其低16位對應先前CPU中的SBP和SP,對低16位數(shù)據(jù)的存取,不影
響高16位的數(shù)據(jù)。
寄存器EBP、ESP、BP和SP稱為指針寄存器(Pointer Register),主要用于存放堆棧內存儲單元的偏移量,
用它們可實現(xiàn)多種存儲器操作數(shù)的尋址方式,為以不同的地址形式訪問存儲單元提供方便。
指針寄存器不可分割成8位寄存器。作為通用寄存器,也可存儲算術邏輯運算的操作數(shù)和運算結果。
它們主要用于訪問堆棧內的存儲單元,并且規(guī)定:
BP為基指針(Base Pointer)寄存器,用它可直接存取堆棧中的數(shù)據(jù);
SP為堆棧指針(Stack Pointer)寄存器,用它只可訪問棧頂。
4、段寄存器
段寄存器是根據(jù)內存分段的管理模式而設置的。內存單元的物理地址由段寄存器的值和一個偏移量組合而成
的,這樣可用兩個較少位數(shù)的值組合成一個可訪問較大物理空間的內存地址。
CPU內部的段寄存器:
CS——代碼段寄存器(Code Segment Register),其值為代碼段的段值;
DS——數(shù)據(jù)段寄存器(Data Segment Register),其值為數(shù)據(jù)段的段值;
ES——附加段寄存器(Extra Segment Register),其值為附加數(shù)據(jù)段的段值;
SS——堆棧段寄存器(Stack Segment Register),其值為堆棧段的段值;
FS——附加段寄存器(Extra Segment Register),其值為附加數(shù)據(jù)段的段值;
GS——附加段寄存器(Extra Segment Register),其值為附加數(shù)據(jù)段的段值。
在16位CPU系統(tǒng)中,它只有4個段寄存器,所以,程序在任何時刻至多有4個正在使用的段可直接訪問;在32位
微機系統(tǒng)中,它有6個段寄存器,所以,在此環(huán)境下開發(fā)的程序最多可同時訪問6個段。
32位CPU有兩個不同的工作方式:實方式和保護方式。在每種方式下,段寄存器的作用是不同的。有關規(guī)定簡
單描述如下:
實方式: 前4個段寄存器CS、DS、ES和SS與先前CPU中的所對應的段寄存器的含義完全一致,內存單元的邏輯
地址仍為“段值:偏移量”的形式。為訪問某內存段內的數(shù)據(jù),必須使用該段寄存器和存儲單元的偏移量。
保護方式: 在此方式下,情況要復雜得多,裝入段寄存器的不再是段值,而是稱為“選擇子”(Selector)的某個值。。
5、指令指針寄存器
32位CPU把指令指針擴展到32位,并記作EIP,EIP的低16位與先前CPU中的IP作用相同。
指令指針EIP、IP(Instruction Pointer)是存放下次將要執(zhí)行的指令在代碼段的偏移量。在具有預取指令功
能的系統(tǒng)中,下次要執(zhí)行的指令通常已被預取到指令隊列中,除非發(fā)生轉移情況。所以,在理解它們的功能
時,不考慮存在指令隊列的情況。
在實方式下,由于每個段的最大范圍為64K,所以,EIP中的高16位肯定都為0,此時,相當于只用其低16位
的IP來反映程序中指令的執(zhí)行次序。
6、標志寄存器
一、運算結果標志位
1、進位標志CF(Carry Flag)
進位標志CF主要用來反映運算是否產(chǎn)生進位或借位。如果運算結果的最高位產(chǎn)生了一個進位或借位,那么,其值為1,否則其值為0。
使用該標志位的情況有:多字(字節(jié))數(shù)的加減運算,無符號數(shù)的大小比較運算,移位操作,字(字節(jié))之間移位,專門改變CF值的指令等。
2、奇偶標志PF(Parity Flag)
奇偶標志PF用于反映運算結果中“1”的個數(shù)的奇偶性。如果“1”的個數(shù)為偶數(shù),則PF的值為1,否則其值為0。
利用PF可進行奇偶校驗檢查,或產(chǎn)生奇偶校驗位。在數(shù)據(jù)傳送過程中,為了提供傳送的可靠性,如果采用奇偶校驗的方法,就可使用該標志位。
3、輔助進位標志AF(Auxiliary Carry Flag)
在發(fā)生下列情況時,輔助進位標志AF的值被置為1,否則其值為0:
(1)、在字操作時,發(fā)生低字節(jié)向高字節(jié)進位或借位時;
(2)、在字節(jié)操作時,發(fā)生低4位向高4位進位或借位時。
對以上6個運算結果標志位,在一般編程情況下,標志位CF、ZF、SF和OF的使用頻率較高,而標志位PF和AF的使用頻率較低。
4、零標志ZF(Zero Flag)
零標志ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標志位。
5、符號標志SF(Sign Flag)
符號標志SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統(tǒng)中,有符號數(shù)采用補碼表示法,所以,SF也就反映運算結果的正負號。運算結果為正數(shù)時,SF的值為0,否則其值為1。
6、溢出標志OF(Overflow Flag)
溢出標志OF用于反映有符號數(shù)加減運算所得結果是否溢出。如果運算結果超過當前運算位數(shù)所能表示的范圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0。
“溢出”和“進位”是兩個不同含義的概念,不要混淆。如果不太清楚的話,請查閱《計算機組成原理》課程中的有關章節(jié)。
二、狀態(tài)控制標志位
狀態(tài)控制標志位是用來控制CPU操作的,它們要通過專門的指令才能使之發(fā)生改變。
1、追蹤標志TF(Trap Flag)
當追蹤標志TF被置為1時,CPU進入單步執(zhí)行方式,即每執(zhí)行一條指令,產(chǎn)生一個單步中斷請求。這種方式主要用于程序的調試。
指令系統(tǒng)中沒有專門的指令來改變標志位TF的值,但程序員可用其它辦法來改變其值。
2、中斷允許標志IF(Interrupt-enable Flag)
中斷允許標志IF是用來決定CPU是否響應CPU外部的可屏蔽中斷發(fā)出的中斷請求。但不管該標志為何值,CPU都必須響應CPU外部的不可屏蔽中斷所發(fā)出的中斷請求,以及CPU內部產(chǎn)生的中斷請求。具體規(guī)定如下:
(1)、當IF=1時,CPU可以響應CPU外部的可屏蔽中斷發(fā)出的中斷請求;
(2)、當IF=0時,CPU不響應CPU外部的可屏蔽中斷發(fā)出的中斷請求。
CPU的指令系統(tǒng)中也有專門的指令來改變標志位IF的值。
3、方向標志DF(Direction Flag)
方向標志DF用來決定在串操作指令執(zhí)行時有關指針寄存器發(fā)生調整的方向。具體規(guī)定在第5.2.11節(jié)——字符串操作指令——中給出。在微機的指令系統(tǒng)中,還提供了專門的指令來改變標志位DF的值。
三、32位標志寄存器增加的標志位
1、I/O特權標志IOPL(I/O Privilege Level)
I/O特權標志用兩位二進制位來表示,也稱為I/O特權級字段。該字段指定了要求執(zhí)行I/O指令的特權級。如果當前的特權級別在數(shù)值上小于等于IOPL的值,那么,該I/O指令可執(zhí)行,否則將發(fā)生一個保護異常。
2、嵌套任務標志NT(Nested Task)
嵌套任務標志NT用來控制中斷返回指令IRET的執(zhí)行。具體規(guī)定如下:
(1)、當NT=0,用堆棧中保存的值恢復EFLAGS、CS和EIP,執(zhí)行常規(guī)的中斷返回操作;
(2)、當NT=1,通過任務轉換實現(xiàn)中斷返回。
3、重啟動標志RF(Restart Flag)
重啟動標志RF用來控制是否接受調試故障。規(guī)定:RF=0時,表示“接受”調試故障,否則拒絕之。在成功執(zhí)行完一條指令后,處理機把RF置為0,當接受到一個非調試故障時,處理機就把它置為1,中國自學編程網(wǎng)整理發(fā)布!。
4、虛擬8086方式標志VM(Virtual 8086 Mode)
如果該標志的值為1,則表示處理機處于虛擬的8086方式下的工作狀態(tài),否則,處理機處于一般保護方式下的工作狀態(tài)。
===================================================
雖然jmp指令提供了控制轉移,但是它不允許進行任何復雜的判斷。80x86條件跳轉指令提供了這種判斷。條件跳轉指令是創(chuàng)建循環(huán)和實現(xiàn)其他條件執(zhí)行語句,如if…endif的基本要素。
條件跳轉指令檢查一個或多個標志位,判斷它們是否匹配某個特殊條件(就像setcc指令):如果標志匹配成功,該指令就將控制轉移到目標位置;如果匹配失敗,CPU忽略該條件跳轉指令而繼續(xù)執(zhí)行下一條指令。一些條件跳轉指令只是簡單測試符號位(sign)、進位位(carry)、溢出位(overflow)、零標志(zero)位的設置。例如,在執(zhí)行一條sh1指令后,您需要測試進位標志,來判斷sh1是否從操作數(shù)的高地址位移出一位。類似地,也可以在一條test指令后測試零標志位,來判斷指定的位是否為1。大多數(shù)情況,在cmp指令之后執(zhí)行條件跳轉指令。cmp指令設置標志位,以便判斷小于、大于、等于等情況。
條件跳轉指令形式如下:
Jcc label;
其中,Jcc中的“cc”,必須用表示測試條件類型的字符序列替換。這些字符和setcc指令使用的一樣。例如,“js”表示根據(jù)符號(sign)標志是否被置位來決定是否跳轉。一個典型的js指令如下:
js ValueIsNegative ;
在這個示例中,如果符號(sign)標志被置位,則js指令將控制轉移到ValueIsNegative語句標號處;如果符號標志清零,則將控制直接轉移給js指令后的指令。
與無條件jmp指令不同,條件跳轉指令不提供間接跳轉的形式。惟一允許的形式是跳轉到程序中某一標號處。條件跳轉指令有一個限制:目標標號的位置必須在跳轉指令本身附近32768字節(jié)范圍內,這通常對應著8000~32000條機器指令。一般情況下不會超過這種限制。
注意:Intel文檔為許多條件跳轉指令定義了多種替代名或指令別名。表7-1、7-2和7-3列出了每個指令所有的別名。這些表格也列出了表示相反分支的指令。很快您將明白這些相反分支指令的作用。
表7-1 測試標志位的JCC指令
指 令
描 述
條 件
別 名
相 反 指 令
JC
如果進位位被置位則跳轉
進位標志=1
JB,JNAE
JNC
JNC
如果進位位沒有置位則跳轉
進位標志=0
JNB,JAE
JC
JZ
如果0標志被置位則跳轉
0標志=1
JE
JNZ
JNZ
如果0標志沒有置位則跳轉
0標志=0
JNE
JZ
(續(xù)表)
指 令
描 述
條 件
別 名
相反指令
JS
如果符號位被置位則跳轉
符號標志=1
JNS
JNS
如果符號位沒有被置位則跳轉
符號標志=0
JS
JO
如果溢出標志置位則跳轉
溢出標志=1
JNO
JNO
如果溢出標志沒有置位則跳轉
溢出標志=0
JO
JP
如果奇偶校驗位被置位則跳轉
奇偶校驗標志=1
JPE
JNP
JPE
如果奇偶校驗位為偶校驗則跳轉
奇偶校驗標志=1
JP
JPO
JNP
如果奇偶校驗位沒有被置位則跳轉
奇偶校驗標志=0
JPO
JP
JPO
如果奇偶校驗位為奇校驗則跳轉
奇偶校驗標志=0
JNP
JPE
表7-2 使用無符號數(shù)比較的JCC指令
指 令
描 述
條 件
別 名
相反指令
JA
如果超過(>)則跳轉
進位標志=0,0標志=0
JNBE
JNA
JNBE
如果不低于或等于(不 <=)則跳轉
進位標志=0,0標志=0
JA
JBE
JAE
如果超過或等于(>=)則跳轉
進位標志=0
JNC,JNB
JNAE
JNB
如果不低于則跳轉(不 <)
進位標志=0
JNC,JAE
JB
JB
如果低于(<)則跳轉
進位標志=1
JC,JNAE
JNB
JNAE
如果不超過或等于(不>=)則跳轉
進位標志=1
JC,JB
JAE
JBE
如果低于或等于(<=)則跳轉
進位標志=1或0標志=1
JNA
JNBE
JNA
如果不超過(不>)則跳轉
進位標志=1或0標志=1
JBE
JA
JE
如果相等(=)則跳轉
0標志=1
JZ
JNE
JNE
如果不相等(<>)則跳轉
0標志=0
JNZ
JE
表7-3 使用有符號數(shù)比較的JCC指令
指 令
描 述
條 件
別 名
相反指令
JG
如果大于(>)則跳轉
符號標志=溢出標志或0標志=0
JNLE
JNG
JNLE
如果小于或等于(<=)則跳轉
符號標志=溢出標志或0標志=0
JG
JLE
JGE
如果大于或等于(>=)則跳轉
符號標志=溢出標志
JNL
JGE
JNL
如果不小于(不<)則跳轉
符號標志=溢出標志
JGE
JL
JL
如果小于(<)則跳轉
符號標志<>溢出標志
JNGE
JNL
JNGE
如果大于或等于(>=)跳轉
符號標志<>溢出標志
JL
JGE
JLE
如果小于或等于(<=)跳轉
符號標志<>溢出標志或0標志=1
JNG
JNLE
JNG
如果不大于(不>)則跳轉
符號標志<>溢出標志或0標志=1
JLE
JG
JE
如果等于(=)則跳轉
0標志=1
JZ
JNE
JNE
如果不等于(<>)則跳轉
0標志=0
JNZ
JE
接下來將對“相反指令”一列進行簡單的說明。在許多情況下,需要產(chǎn)生與某條分支指令條件相反的分支(在本章后面會給出示例),即相反分支。除了兩個例外,都可以按下面的簡單規(guī)則(后面統(tǒng)稱為N/No N規(guī)則)產(chǎn)生相反分支:
● 如果Jcc的第二個字母不是“n”,則在“j”后面插入一個“n”。例如:je對應為jne,jl對應為jnl。
● 如果Jcc的第二個字母是“n”,則去掉指令中的“n”。例如:jng對應為jg,jne對應為je。
不遵循這兩條規(guī)則的兩個例外是jpe(奇偶位為偶跳轉)和jpo(奇偶位為奇跳轉)。這兩個例外并不會導致什么問題,因為:(a)很少需要測試奇偶標志;(b)可以使用別名jp和jnp替代jpe和jpo。而“N/No N”規(guī)則對jp和jnp是適用的。
雖然jge是jl的相反指令,但是建議使用jnl作為jl的相反指令。因為很容易誤認為“大于是小于的相反”,從而把jg當作jl的相反指令。您可以堅持使用“N/No N”規(guī)則以避免這種混淆。
80x86條件跳轉指令提供了這樣的能力:根據(jù)判斷條件將程序流分支到兩條路徑中的某一條。例如,要實現(xiàn):如果BX等于CX,則寄存器AX的值加1??梢允褂孟旅娴拇a來完成該功能:
cmp(bx,cx );
jne SkipStmts;
inc(ax );
SkipStmts:
其中的訣竅是使用相反分支指令來跳過在條件滿足的情況下需要執(zhí)行的指令。請堅持使用前面介紹的“N/no N”規(guī)則來選擇相反分支指令。
使用條件跳轉指令還可以實現(xiàn)循環(huán)。例如,下面的代碼序列實現(xiàn)了從用戶輸入讀入一串字符,并將字符存儲到一組連續(xù)的單元中,直到用戶輸入回車鍵。
mov(0,edi );
RdLnLoop:
stdin.getc(); //Read a character into the AL register.
mov(al,Input [edi])); //Store away the character.
inc(edi ); //Move on to the next character.
cmp(al,stdio.cr ); //See if the user pressed Enter.
jne RdLnLoop;
與setcc指令類似,條件跳轉指令分為兩類—— 測試特殊處理器標志位的條件跳轉指令(例如jz、jc、jno)和測試某些條件(小于、大于等)的條件跳轉指令。當測試某個條件時,條件跳轉指令通常緊跟在一個cmp指令之后。cmp指令設置標志位后,如果是無符號數(shù)比較,使用ja、jae、jb、jbe、je或jne等指令測試這些標志來判斷是否小于、小于等于、等于、不等于、大于或大于等于;如果是有符號數(shù)比較,則使用jl、jle、je、jne、jg、jge指令。
條件跳轉指令測試標志位,但不影響標志位。
=========================
jnz(jump if not zero flag set) 和 jne(jump if not equal) 有相同的功效。
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
x86匯編指令詳解
lea指令與mov指令
MUL、IMUL、DIV
七種尋址方式(立即尋址、寄存器尋址)
80386ASM程序設計基礎(二)
FASM 第二章 - 2.1 x86 體系指令 - xuyibo.org
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服