王爽汇编第三版实验10.3 浅析

来源:互联网 发布:淘宝店铺网址怎么复制 编辑:程序博客网 时间:2024/05/17 23:16

同实验10.2,不上题目了。

题目大概就是说,将保存在数据段的字型的数值,以10进制的方式显示在屏幕上。这里涉及到两点,一是打印到屏幕,即打印到内存空间B8000H~BFFFFH之间,其中每个字符占一个字,高位存放属性,低位存放字符,这段32KB的空间共可以显示25*80个字符,也就是每行80*2=160个字节。

二就是将存放在内存当中的二进制数值(以十六进制的方式显示),转换成10进制。因为显存只认识ASCII码,又因为数据在内存中是以十六进制显示的,所以我们将在数据段中的数值变为ASCII码中的十六进制。

0~9在ASCII码中的范围是30H~39H,我们要将数字中的每一位都转换成这种形式。

怎么取每一位,用书上讲的一直除10,除到商为0时,就结束。这种方法得到的每一位的顺序刚好是相反的,即12366取每一位的顺序是66321,这样我们可以用栈来解决,每取到一位,加上30H,然后进栈,最后我们要打印的时候依次取出来就行了。

到了这里还有一些问题,比如:你取位的时候可以通过判断商是否为0来结束,那么你打印的时候又怎么判断有多少位?我一开始想到的是在循环里面计数,可是难以实现,因为寄存器不够用,而我又不想用。当然你可以在栈顶(SS:[0])中来计数,每打印完一个数,就清零,这种方法我还没有去实现,还有另外一种方法就是,根据SP寄存器的相对偏移来确定到底有几位,我用的就是这种方法。

然后还有,如果数据段的数不止一个数,那么怎么判断后面是否还有数?这个我们可以根据0来判断,我们可以在数据段的最后加一个0,然后每次读其中的数的时候,把这个数的值给CX,用JCXZ来结束程序。

下面放代码

DATAS SEGMENT    dw 123,12366,1,8,3,38,9;此处输入数据段代码  DATAS ENDSSTACKS SEGMENT    dw 200 dup(0);此处输入堆栈段代码STACKS ENDSCODES SEGMENT    ASSUME CS:CODES,DS:DATAS,SS:STACKSSTART:    MOV AX,DATAS    MOV DS,AX        MOV AX,0B800H    MOV ES,AX    MOV DI,0    MOV SI,0        MOV AX,STACKS    MOV SS,AX MOV SP,801  MOV DH,8   ;行    MOV DL,3;列    MOV CL,2;颜色sub dl,1MOV AL,160MUL DHMOV DI,AX;计算行偏移MOV AX,2MUL DLADD DI,AX;行+列偏移 保存在DI     CALL dtoc            MOV AX,4C00H    INT 21H show_str: MOV CL,2;颜色push cx   ;颜色进栈MOV CX,801SUB CX,SPMOV AX,CXMOV Bl,2DIV BlSUB AX,2MOV CX,AX;计算CX的值p:POP BX;颜色出栈POP DXMOV ES:[DI],DLMOV ES:[DI+1],bladd DI,2PUSH BXLOOP pPOP BXadd SI,2jmp short dtocdtoc:MOV AX,DS:[SI]MOV CX,AXJCXZ returns:MOV CL,ALMOV CH,0JCXZ ok;商为0时打印MOV DX,0MOV BX,10DIV BX;商在AX 余数在DXMOV BX, 30HADD DX,BXPUSH DXjmp short sok:jmp  short show_strreturn:retCODES ENDS    END START

做题目的时候差点被坑,因为这里12366/10,也就是 16位/8位,商保存在AL,余数保存在AH,然后就会发生溢出错误,因为AL保存不了这么大的值,这里只能用32位/16位来解决。在打印的计算CX那里,用SP最开始的值-当前的SP的值,再除2,因栈是字为单位的,一个字等于两个字节,然后在-2,为什么要-2呢?

因为在CODES段中 CALL了 dtoc ,这时候CPU会把CALL的下一个地址进栈,然后在show_str中把颜色进栈了,所以我们要减去2,就能得到正确的CX结果了。还有在p段结束后,要记得POP BX,因为最后一个循环PUSH了一个值,如果不将其出栈,那么CALL dtoc的下一条指令就不会执行,程序就不能正常结束。

还有一点 就是关于列的,为什么要-1 。因为第三列(现实生活的计数,从1开始)就是里面的第二列,00 01 02 03 04 05,我们要定位到04这个内存单元,我们可以(3-1)*2,等于4。

以后想到再补充了,欢迎大家一起学习交流。

原创粉丝点击