1,显示字符串
assume cs:codesg, ds:datasgdatasg segmentdb 'hello, world', 0
datasg endscodesg segment
start: mov dh, 14mov dl, 40mov cl, 2mov ax, datasgmov ds, axmov si, 0 ;si point to datacall show_strmov ax, 4c00hint 21h;-------show_str---------------
show_str:push sipush dipush cxpush bxmov bl, clmov ax, 0b800hmov es, axmov di, 0mov al, 160mul dhmov di, axmov al, 2 ;es:di point to display memorymul dladd di, axs: xor cx, cxmov cl, ds:[si]jcxz okmov es:[di+0], clmov es:[di+1], bladd si, 1add di, 2jmp sok: pop bxpop cxpop dipop siretcodesg 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:datadata segmentdw 8 dup(0)
data endscodesg segment
start: mov ax, 4240hmov dx, 000fhmov cx, 0ahcall divdwmov ax, 4c00hint 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 axpush bxpush cxpush dxpush sichange_dtoc:mov cx, 10xor dx, dxcall divdwxor ch, chadd cl, 30hmov ds:[di], cl ;把余数暂存到内存2中inc dimov cx, ax ;检查商是否为0jcxz dtoc_retjmp change_dtocdtoc_ret:mov cx, disub di, 1
loop_s: mov bl, ds:[di]sub di, 1mov ds:[si], blinc siloop loop_spop sipop dxpop cxpop bxpop axret
本程序比较伤脑筋的地方就是求出来数字的顺序是从低位到高位,而输出的顺序是从高位到低位,这里有一个比较好的办法是先把数字从低位到高位存放到数据段中的后边某个位置,然后再反序复制到0位置开始的数据段中。
加油!