当前位置: 代码迷 >> 汇编语言 >> .问2段<显示字符串>的程序,对代码不太明白.该怎么处理
  详细解决方案

.问2段<显示字符串>的程序,对代码不太明白.该怎么处理

热度:3735   发布时间:2013-02-26 00:00:00.0
.....问2段<显示字符串>的程序,对代码不太明白...
;   ------------------------------------------------------------------------
;   显示   AL   中的数字
;   默认地:
; 数字已经存在   AL   中
; edi   始终指向要显示的下一个字符的位置
;   被改变的寄存器:
; ax,   edi
;   ------------------------------------------------------------------------
DispAL:
push ecx
push edx

mov ah,   0Ch ;   0000:   黑底         1100:   红字
mov dl,   al
shr al,   4
mov ecx,   2
.begin:
and al,   01111b
cmp al,   9
ja .1
add al,   '0 '
jmp .2
.1:
sub al,   0Ah
add al,   'A '
.2:
mov [gs:edi],   ax
add edi,   2

mov al,   dl
loop .begin
add edi,   2

pop edx
pop ecx

ret
;   DispAL   结束-------------------------------------------------------------


gs指向显存

;   ------------------------------------------------------------------------
DispReturn:
push eax
push ebx
mov eax,   edi
mov bl,   160
div bl
and eax,   0FFh     ;   为什么要用ADD????
inc eax
mov bl,   160
mul bl
mov edi,   eax
pop ebx
pop eax

ret
;   DispReturn   结束---------------------------------------------------------



------解决方案--------------------------------------------------------
andeax, 0FFh ; 为什么要用ADD????

不是ADD,而是AND,目的是去处显存地址中的高字,保留低字,因为AL中存放的是商,AH中存放的是余数。下面还有用这个“(商+1)*160” 来计算换行后的首字符地址。不过这个换行过程存在隐患,当过程的入口参数edi的实际值大于65536时,此过程将不再能正常工作!因为这个过程假设edi的低字有效。
------解决方案--------------------------------------------------------
al是八位寄存器,可以存储2个16进制位,例如AL=5F。
andal, 01111b 执行后al=0F。

下面的判断是:
if(al> 9)
al=al+31 ;转化为字母(F)为ASCII码
else
al=al+30 ;转化数字为ASCII码

subal, 0Ah
addal, 'A '
就等于
add al,31

mov[gs:edi], ax; 写入显存
addedi, 2 ; 移动显存指针

movdl, al ;目的是保持AL的低半字节

第一次执行循环体前shral, 4是为了先转化高半字节

自己好好研究一下
  相关解决方案