1,显示字符串
assume cs:codesg, ds:datasg
datasg segment
db 'hello, world', 0
datasg ends
codesg segment
start: mov dh, 14
mov dl, 40
mov cl, 2
mov ax, datasg
mov ds, ax
mov si, 0 ;si point to data
call show_str
mov ax, 4c00h
int 21h
;-------show_str---------------
show_str:
push si
push di
push cx
push bx
mov bl, cl
mov ax, 0b800h
mov es, ax
mov di, 0
mov al, 160
mul dh
mov di, ax
mov al, 2 ;es:di point to display memory
mul dl
add di, ax
s: xor cx, cx
mov cl, ds:[si]
jcxz ok
mov es:[di+0], cl
mov es:[di+1], bl
add si, 1
add di, 2
jmp s
ok: pop bx
pop cx
pop di
pop si
ret
codesg ends
end start
实验结果:
2,解决除法溢出的问题
复习一下常规cpu中div指令的设计:
(1)除数:有8位和16位两种,在一个reg或者内存单元中;
(2)被除数:默认放在ax或者dx和ax中,如果除数为8位,则被除数为16位,默认放在ax中;如果除数为16位,被除数则位32位,在dx和ax中存放,dx存放高位,ax存放低位;
(3)结果:如果除数为8位,则al存放商,ah存放余数;如果除数为16位,则ax存放商,dx存放余数。
现在要求的divdw功能是:被除数为dword型,除数为word型,结果为dword型,其中dx存放高16位,ax存放低16位,cx存放余数。
代码如下:
assume cs:codesg, ds:data
data segment
dw 8 dup(0)
data ends
codesg segment
start: mov ax, 4240h
mov dx, 000fh
mov cx, 0ah
call divdw
mov ax, 4c00h
int 21h
;----------divdw--------------
divdw:
push bx
push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax ;将商的高位临时放到bx中
pop ax
div cx ;上一步div的余数(在dx中)做高位,连同ax中的数据(低位)一起做被除数
mov cx,dx ;将余数给cx
mov dx,bx
pop bx
ret
codesg ends
end start
上面的算法完全按照 X/N=INT(H/N)*10000H+[REM(H/N)*10000H+L]/N(在课本208页),对照代码分析,一点都不难。
很多事情难,是因为一直拖延,不敢开始;
很多事情难,是因为太急,没有坚持而匆匆放弃;
很多事情难,是因为只是看了一眼难。
加油。
3,数值显示
;dtoc---------------------------
dtoc: push ax
push bx
push cx
push dx
push si
change_dtoc:
mov cx, 10
xor dx, dx
call divdw
xor ch, ch
add cl, 30h
mov ds:[di], cl ;把余数暂存到内存2中
inc di
mov cx, ax ;检查商是否为0
jcxz dtoc_ret
jmp change_dtoc
dtoc_ret:
mov cx, di
sub di, 1
loop_s:
mov bl, ds:[di]
sub di, 1
mov ds:[si], bl
inc si
loop loop_s
pop si
pop dx
pop cx
pop bx
pop ax
ret
加油!