1. RET && RETF 指令
CPU 執(zhí)行 ret 指令時,進(jìn)行下面兩部操作:
(1)(IP) = ((SS)*16+(SP))
(2)(SP)=(SP)+2CPU 執(zhí)行 retf 指令時,進(jìn)行下面兩部操作:
(1)(IP) = ((SS)16+(SP))
(2)(SP)=(SP)+2
(3)(CS) = ((SS)16+(SP))
(4)(SP)=(SP)+2k可以看出,如果用匯編語法來解釋 ret,retf 指令,則:
CPU 執(zhí)行 ret 指令時,相當(dāng)于:
pop IP
CPU 執(zhí)行 retf 指令時,相當(dāng)于:
pop IP
pop CS
2. CALL 指令
CPU 執(zhí)行 call 指令時,進(jìn)行下面兩部操作:
(1) 將當(dāng)前的 IP 或 CS 和 IP 壓入 棧中;
(2) 轉(zhuǎn)移;call指令不能實現(xiàn)短轉(zhuǎn)移,call指令實現(xiàn)轉(zhuǎn)移的方法和jmp指令的原理相同。
2. 依據(jù)位移進(jìn)行轉(zhuǎn)移的 CALL 指令
- call 標(biāo)號(將當(dāng)前的 IP 壓棧后,轉(zhuǎn)移到標(biāo)號處執(zhí)行指令。)
CPU 執(zhí)行此種格式的 call 指令后,會進(jìn)行如下的操作:
(1)(SP)=(SP)-2
((SS)*16+(SP))=(IP)
(2)(IP) = (IP) + 16位位移
相當(dāng)于:
push IP
jmp near ptr 標(biāo)號
3. 轉(zhuǎn)移的目的地址在指令中的 CALL 指令
call far ptr 標(biāo)號 實現(xiàn)的是段間轉(zhuǎn)移
CPU 執(zhí)行此種格式的 call 指令后,會進(jìn)行如下的操作:
(1)(SP)=(SP)-2
((SS)16+(SP))=(CS)
(SP)=(SP)-2
((SS)16+(SP))=(IP)
(2)(CS) = 標(biāo)號所在段的段地址
(IP)= 標(biāo)號所在段中的偏移地址
相當(dāng)于:
push CS
push IP
jmp far ptr 標(biāo)號
4. 位移地址寄存器中的 CALL 指令
call 16位reg
CPU 執(zhí)行此種格式的 call 指令后,會進(jìn)行如下的操作:
(1)(SP)=(SP)-2
((SS)*16+(SP))=(IP)
(IP)= (16位reg)
相當(dāng)于:
push IP
jmp 16位 reg
4. 位移地址內(nèi)存中的 CALL 指令
(1)call word ptr 內(nèi)存單元地址
push ip
jmp word ptr 內(nèi)存單元地址
(2)call dword ptr 內(nèi)存單元地址
push cs
push ip
jmp dword ptr 內(nèi)存單元地址
5. CALL RET 配合使用
assume cs:code
code segment
main: :
:
call sub1
:
:
mov ax,4c00h
int 21h
sub1 :
:
call sub2
:
ret
sub2 :
:
ret
code ends
end main
5. mul 指令
- 格式如下:
mul reg
mul 內(nèi)存單元 - 注意點:
(1)兩個相乘的數(shù):
兩個相乘的數(shù),要么都是8位,要么都是16位。
如果是8位,一個默認(rèn)存放在 AL 中,另一個存放在 8 位reg 或者 內(nèi)存字節(jié)單位中;
如果是16位,一個默認(rèn)存放在 AX 中,另一個存放在 16 位reg 或者 內(nèi)存字單位中;
(2)結(jié)果:
如果是8位乘法,結(jié)果默認(rèn)存放在 AX 中;
如果是16位乘法,結(jié)果高位默認(rèn)在DX中存放, 地位在AX中存放。
6. 參數(shù)和結(jié)果傳遞
assume cs:codesg,ds:datasg
datasg segment
dw 1,2,3,4,5,6,7,8
dd 0,0,0,0,0,0,0,0
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov si,0
mov di,10h
mov cx,8
s: mov bx,[si]
call cube
mov [di],ax
mov [di].2,dx
add si,2
add di,4
loop s
mov ax,4c00h
int 21h
cube: mov ax,bx
mul bx
mul bx
ret
codesg ends
end start
6. 批量數(shù)據(jù)的傳遞
assume cs:codesg,ds:datasg
datasg segment
db 'conversation'
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov si,0
mov cx,12
call capital
mov ax,4c00h
int 21h
capital: and byte ptr [si],11011111b
inc si
loop capital
ret
codesg ends
end start
6. 用棧傳遞參數(shù)
assume cs:codesg,ss:stacksg
stacksg segment
dw 8 dup (0)
stacksg ends
codesg segment
start: mov ax,stacksg
mov ss,ax
mov sp,10h
mov ax,1
push ax
mov ax,3
push ax
call difcube
mov ax,4c00h
int 21h
difcube: push bp
mov bp,sp
mov ax,[bp+4]
sub ax,[bp+6]
mov bp,ax
mul bp
mul bp
pop bp
ret 4
codesg ends
end start
7. 寄存器沖突問題
assume cs:codesg,ds:datasg
datasg segment
db 'word',0
db 'unix',0
db 'wind',0
db 'good',0
datasg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov bx,0
mov cx,4
s: mov si,bx
call capital
add bx,5
loop s
mov ax,4c00h
int 21h
capital: push cx
push si
change: mov cl,[si]
mov ch,0
jcxz ok
and byte ptr [si],11011111b
inc si
jmp short change
ok: pop si
pop cx
ret
codesg ends
end start
8. 顯式字符串
在第8行的第三列,用綠色顯式 data 段中的字符串:
assume cs:codesg,ds:datasg
datasg segment
db 'welcome to masm!',0
datasg ends
codesg segment
start: mov dh,8
mov dl,3
mov cl,2
mov ax,datasg
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str: push cx
push si
push di
push bx
mov ax,0B800H
mov es,ax
mov di,0
mov al,160
mul dh
mov bx,ax
mov al,2
mul dl
add ax,bx
mov bx,ax
mov ah,cl
show: mov cl,ds:[si]
mov ch,0
jcxz ok
mov al,ds:[si]
mov es:[bx+di],al
mov es:[bx+di+1],ah
inc si
add di,2
jmp short show
ok: pop bx
pop di
pop si
pop cx
ret
codesg ends
end start
8. 進(jìn)行不會產(chǎn)生溢出的出發(fā)運算
assume cs:codesg
codesg segment
start: mov ax,4240H
mov dx,000FH
mov cx,0AH
call divdw
mov ax,4c00h
int 21h
divdw: push bx
mov bx,ax
mov ax,dx
mov dx,0000H
div cx
push ax
mov ax,bx
div cx
mov cx,dx
pop dx
pop bx
ret
codesg ends
end start