ret 和 retf
ret指令用栈中的数据,修改IP的内容,实现近转移。
retf指令用栈中的数据,修改CS和IP的内容,实现远转移。
CPU执行ret指令时,相当于:
pop IPCPU执行retf指令时,相当于:
pop IP
pop CS
CALL指令
CPU进行CALL指令时,进行两步操作:
- 将当前的IP或CS和IP压入栈中
- 转移
- 依据位移进行转移的call指令
call 标号
将当前的IP(cll指令后的第一个字节偏移地址)压入栈后,转移到标号处执行指令。
CPU执行call 标号时,相当于进行:
push IP
jmp near ptr 标号
- 转移的目的地址在指令中的call指令
call far ptr 标号
(CS) = 标号所在段的段地址
(IP) = 标号所在段中的偏移地址
相当于执行:
push CS
push IP
jmp far ptr 标号
- 转移地址在寄存器中的call指令
call 16位reg
相当于进行:
push IP
jmp 16位reg
- 转移地址在内存中的call指令
有两种格式:
段内转移
call word ptr 内存单元地址
相当于进行:
push IP
jmp word ptr 内存单元地址
段间转移
call dword ptr 内存单元地址
相当于进行:
push CS
push IP
jmp dword ptr 内存单元地址
mul指令
mul是乘法指令:
- 两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认放在AL中,另一个放在8位reg或内存字节单元中;如果是16位,一个默认在AX中,另一个放在16位reg或内存字单元中。
- 如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中存放,低位在AX中放。
mul reg
mul 内存单元
mul byte ptr ds:[0]
参数和结果传递的问题
assume cs:code
data segment
dw 1,2,3,4,5,6,7,8
dd 0,0,0,0,0,0,0,0
data ends
code segment
start: mov ax,data
mov ds,ax
mov si,0 ;ds:si指向第一组word单元
mov di,16 ;ds:di指向第二组dword单元
mov cx,8
s: mov bx,[si]
call cube
mov [di],ax ;低位存放在AX中
mov [di].2,dx ;高位存放在DX中
add si,2
add di,4
loop s
mov ax,4c00h
int 21h
cube: mov ax,bx
mul bx
mul bx
ret
code ends
end start
寄存器冲突问题
例子:将data段中的字符串全部转化为大写
assume cs:code
data segment
db 'word',0
db 'unix',0
data ends
code segment
start: mov ax,data
mov ds,ax
mov bx,0
mov cx,2 ;循环次数2
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] ;把cs:si所指向的元素传入cl,
mov ch,0 ;以判断(cx)是否为零
jcxz ok ;(cx)为零时转跳,不为零时顺序进行
and byte ptr [si],11011111b
inc si
jmp short change
ok: pop si
pop cx
ret
code ends
end start