鱼C论坛

 找回密码
 立即注册
查看: 1885|回复: 4

一个周了一直在编写10章节的实验子程序,最后一个大牛帮忙看看,在此谢过!

[复制链接]
发表于 2012-12-2 01:37:59 | 显示全部楼层 |阅读模式
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
QQ截图20121202012854.png

最佳答案

查看完整内容

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 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-2 01:38:00 | 显示全部楼层
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
               
                cmp ax,0
                je loops
                jmp 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-12-2 10:17:17 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-12-2 10:21:06 | 显示全部楼层
不过,JE指令小弟还没有学到。标志位还木懂啥意思。我看了您的解答,忽然发现我加了条件判断后又重复使用了loop指令,至使CX值发现变化。我把loop cstr1,改成jmp cstr1,就成功了执行了。非常感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-12-2 10:43:47 | 显示全部楼层
lyoal 发表于 2012-12-2 10:21
不过,JE指令小弟还没有学到。标志位还木懂啥意思。我看了您的解答,忽然发现我加了条件判断后又重复使用了 ...

一起加油!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-8 00:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表