鱼C论坛

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

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

[复制链接]
发表于 2012-12-2 01:37:59 | 显示全部楼层 |阅读模式
1鱼币
本帖最后由 lyoal 于 2012-12-2 01:37 编辑

这个程序整了两小时写出来了,按自己的思路写的。12666字符串在我的本本上,无论怎么调示都是显示b2666.
但是如果将AX的数据改为32666就能正常显示,求大牛帮忙解释一下,这是为啥类?
请看代码:
  1. assume cs:code,ds:data
  2. data segment
  3.         db 0 dup (0)
  4. data ends

  5. stack segment
  6.         db 50 dup (0)
  7. stack ends

  8. code segment
  9. start:        mov ax,12666                ;定义一个数据,用于将数据转化成字符串显示出来
  10.                 mov bx,data
  11.                 mov ds,bx                        ;关联数据段
  12.                 mov bx,stack
  13.                 mov ss,bx
  14.                 mov sp,50
  15.                  
  16.                 mov bx,0                        ;用来计数
  17.                
  18.                 call cstr
  19.                
  20.                 mov dh,8                        ;定义字符串在显卡中的定位,第8行
  21.                 mov dl,11                        ;第3列
  22.                 mov cl,0cah                        ;颜色值
  23.                
  24.                 call show_str
  25.                
  26.                 mov ax,4c00h
  27.                 int 21h
  28.                
  29.                
  30.                
  31. cstr:        push ax                                ;将需要用到的寄存器的原始数据入栈
  32.                 push bx
  33.                 push cx
  34.                 push si
  35.                 push di
  36.                 push dx



  37. cstr1:        ;mov cx,0
  38.                 mov cx,10d                        ;定义一个十进制数据的10,用作除数与被除数12666进行运算,方法是取余法
  39.                 mov dx,0                        ;先将用于存放余数的寄存器DX置0
  40.                 div cx                                ;AX/CX(为什么除数为AL时会溢出呢?)
  41.                
  42.                 mov cx,ax                         ;将余数送入CX中,用判断余数是否为0,当余数为0时,表示被除数被除尽,则进行跳转(将商为0作为判断条件)
  43.                 jcxz loops
  44.                
  45.                 add dx,30h                        ;将余数转化为ASCII码字符
  46.                 push dx                         ;暂将转换成的字符压入栈中
  47.                 inc bx
  48.                 loop cstr1
  49.                
  50.                
  51. loops:        add dx,30h                        ;因为余数为0条件成立后,最后一位字符未被进行转换,这里对其进行转换并入栈
  52.                 push dx
  53.                 inc bx
  54.                
  55.                 mov cx,bx                        ;将计数器中的数据传送给CX用于循环,将栈中的字符依次送入数据段DS中
  56.                 mov si,0                        ;索引DS数据段中的位置或着说是用于定位
  57.                

  58. s:                pop ax
  59.                 mov [si],al                        ;将出栈的字符送入到数据段DS中去
  60.                 inc si
  61.                 loop s
  62.                
  63.                
  64. ok:                pop dx                                ;数据处理完成后,将原始数据出栈
  65.                 pop di
  66.                 pop si
  67.                 pop cx
  68.                 pop bx
  69.                 pop ax
  70.                 ret                                        ;返回
  71.                
  72.                
  73.                
  74. show_str:        push ax                        ;寄存器原始数据入栈
  75.                         push bx
  76.                         push cx
  77.                         push dx
  78.                         push si
  79.                         push di
  80.                         
  81.                         mov ax,0b800h
  82.                         mov es,ax                ;将显存的段地址关联给ES段寄存器
  83.                         
  84.                         dec dh
  85.                         mov ax,0                ;谨慎一点将AX寄存器置0一下
  86.                         mov bx,0
  87.                         mov ax,0a0h                ;将显存中一行的字节数的宽度给AX
  88.                         mul dh                        ;现在AX中存放的就是显存中前7行的偏移地址
  89.                         mov bx,ax                ;将结果送入DX寄存器存放,AX接下来用于计算列的偏移地址
  90.                         
  91.                         mov ax,0
  92.                         dec dl                        ;曾经让我纠结的地方,因80个字符位置,每一个字符位包含一个字节给数据,一个字节给颜色。所以两列四字节才能显示一个带有颜色的字符,显示一个完整字符
  93.                                                         ;必须将字符放在偶数位,颜色放在奇数位,故减去一列
  94.                         mul dl
  95.                         add bx,ax                ;至此,DX寄存器中存放着显存的前8行第2列的偏移地址
  96.                         
  97.                         mov ch,0                ;目的是用于判断CX寄存器是否为0
  98.                         mov al,cl                ;将CL寄存器中的颜色送入到AL中
  99.                         mov si,0
  100.                         mov di,0
  101.                         
  102. s1:                        mov cl,[si]
  103.                         jcxz okey                ;当CX为0时跳转返回
  104.                         mov byte ptr es:[bx+di],cl
  105.                         mov byte ptr es:[bx+di+1],al
  106.                         inc si
  107.                         add di,2
  108.                         loop s1
  109.                         
  110.                         
  111. okey:                pop di
  112.                         pop si
  113.                         pop dx
  114.                         pop cx
  115.                         pop bx
  116.                         pop ax
  117.                         ret
  118.                         
  119.                         code ends
  120. 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 ...
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-12-2 10:17:17 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

一起加油!!!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-3 12:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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