|
1鱼币
本帖最后由 lyoal 于 2012-12-2 01:37 编辑
这个程序整了两小时写出来了,按自己的思路写的。12666字符串在我的本本上,无论怎么调示都是显示b2666.
但是如果将AX的数据改为32666就能正常显示,求大牛帮忙解释一下,这是为啥类?
请看代码:assume cs:code,ds:data
data segment
db 0 dup (0)
data ends
stack segment
db 50 dup (0)
stack ends
code segment
start: mov ax,12666 ;定义一个数据,用于将数据转化成字符串显示出来
mov bx,data
mov ds,bx ;关联数据段
mov bx,stack
mov ss,bx
mov sp,50
mov bx,0 ;用来计数
call cstr
mov dh,8 ;定义字符串在显卡中的定位,第8行
mov dl,11 ;第3列
mov cl,0cah ;颜色值
call show_str
mov ax,4c00h
int 21h
cstr: push ax ;将需要用到的寄存器的原始数据入栈
push bx
push cx
push si
push di
push dx
cstr1: ;mov cx,0
mov cx,10d ;定义一个十进制数据的10,用作除数与被除数12666进行运算,方法是取余法
mov dx,0 ;先将用于存放余数的寄存器DX置0
div cx ;AX/CX(为什么除数为AL时会溢出呢?)
mov cx,ax ;将余数送入CX中,用判断余数是否为0,当余数为0时,表示被除数被除尽,则进行跳转(将商为0作为判断条件)
jcxz loops
add dx,30h ;将余数转化为ASCII码字符
push dx ;暂将转换成的字符压入栈中
inc bx
loop cstr1
loops: add dx,30h ;因为余数为0条件成立后,最后一位字符未被进行转换,这里对其进行转换并入栈
push dx
inc bx
mov cx,bx ;将计数器中的数据传送给CX用于循环,将栈中的字符依次送入数据段DS中
mov si,0 ;索引DS数据段中的位置或着说是用于定位
s: pop ax
mov [si],al ;将出栈的字符送入到数据段DS中去
inc si
loop s
ok: pop dx ;数据处理完成后,将原始数据出栈
pop di
pop si
pop cx
pop bx
pop ax
ret ;返回
show_str: push ax ;寄存器原始数据入栈
push bx
push cx
push dx
push si
push di
mov ax,0b800h
mov es,ax ;将显存的段地址关联给ES段寄存器
dec dh
mov ax,0 ;谨慎一点将AX寄存器置0一下
mov bx,0
mov ax,0a0h ;将显存中一行的字节数的宽度给AX
mul dh ;现在AX中存放的就是显存中前7行的偏移地址
mov bx,ax ;将结果送入DX寄存器存放,AX接下来用于计算列的偏移地址
mov ax,0
dec dl ;曾经让我纠结的地方,因80个字符位置,每一个字符位包含一个字节给数据,一个字节给颜色。所以两列四字节才能显示一个带有颜色的字符,显示一个完整字符
;必须将字符放在偶数位,颜色放在奇数位,故减去一列
mul dl
add bx,ax ;至此,DX寄存器中存放着显存的前8行第2列的偏移地址
mov ch,0 ;目的是用于判断CX寄存器是否为0
mov al,cl ;将CL寄存器中的颜色送入到AL中
mov si,0
mov di,0
s1: mov cl,[si]
jcxz okey ;当CX为0时跳转返回
mov byte ptr es:[bx+di],cl
mov byte ptr es:[bx+di+1],al
inc si
add di,2
loop s1
okey: pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start
|
最佳答案
查看完整内容
assume cs:code,ds:data
data segment
db 0 dup (0)
data ends
stack segment
db 50 dup (0)
stack ends
code segment
start: mov ax,12666 ;定义一个数据,用于将数据转化成字符串显示出来
mov bx,data
mov ds,bx ;关联数据段
mov bx,stack
mov ss,bx
mov sp,50
...
|