mul指令
两个相乘的数都是8位:
一个默认放在AL中,另一个放在8位reg或内存字节单元中。结果默认存放于AX中。
例如:100*10
mov al,100
mov bl,10
mul bl
结果:(AX)=1000(03E8H)
两个相乘的数都是16位:
一个默认存放在A中,另一个存放在16位reg或内存字单元中。结果高位默认存放在DX中,低位存放在AX中。
例如:100*10000
mov ax,100
mov bx,10
mul bx
结果:(AX)=4240H,(DX)=000FH 1000000=F4240H
模块化程序设计
当程序越来越复杂,我们可以利用函数的特点,将一个大问题分解成若干个子问题,再分别解决每一个子问题。可以让程序模块化,逻辑更加清晰。
call不仅可以跳转执行其后面的子程序,也可以向子程序传递参数、获得子程序的返回值。
例如,计算N的3次方,参数为N。
assume cs:codesg
data segment
dw 1,2,3,4,5,6,7,8
dd 0,0,0,0,0,0,0,0
data ends
codesg segment
start:mov ax,data
mov ds,ax
mov si,0
mov di,16
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
数据段为1,2,3,4,5,6,7,8,通过循环分别计算cube(i),计算的结果每一次临时值高8位在DX中,第8位在AX中。
si是原始参数的偏移,di是将每一次临时值的结果存储起来,每一次偏移16位。
批量数据传递
求立方程序传递参数只有一个,使用一个si偏移寄存器。如果参数有2个、3个、多个,寄存器的数量一定会出现不够用情况。因此,可以将多个参数批量放到内存中,将内存空间首地址传递给子程序。
如下程序,将小写字母“blackcat”转化为大写:
assume cs:codesg
data segment
db 'blackcat'
data ends
codesg segment
start:mov ax,data
mov ds,ax
mov si,0
mov cx,8
call work
mov ax,4c00H
int 21H
work:and byte ptr [si],11011111b
inc si
loop work
ret
codesg ends
end start
字符串首地址为ds:[si],work子程序循环读取每一个参数,将cx寄存器赋值为字符串长度。