鱼C论坛

 找回密码
 立即注册
查看: 28|回复: 1

[学习笔记] 8086汇编实验十第三题

[复制链接]
发表于 昨天 19:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
学习笔记
8086汇编实验十第三题
  1. assume cs:code

  2. data segment

  3.         db 10 dup(0)

  4. data ends


  5. code segment

  6. start:       
  7.                 mov ax,12666                        ;定义将要显示的数据
  8.                 mov bx,data
  9.                 mov ds,bx
  10.                 mov si,0
  11.                 call dtoc                                ;子程序,将二进制信息转变为十进制字符串
  12.                
  13.                 mov dh,8
  14.                 mov dl,3
  15.                 mov cl,2                                ;定义字符串目标地址行数、列数、颜色属性
  16.                 call show_str                        ;子程序,将字符串显示在目标位置
  17.                
  18.                 mov ah,00h
  19.                 int 16h
  20.                
  21.                 mov ax,4c00h
  22.                 int 21h
  23.                
  24.                
  25. dtoc:                ;将二进制信息转变为十进制字符串,子程序开始
  26.                         push dx
  27.                         push cx
  28.                         push ax
  29.                         push si
  30.                         push bx                                ;保存原始数据

  31.                         mov bx,10                        ;方便后面数字除10
  32.                         mov dx,0                        ;dx归零,方便后续计算
  33.                         push dx                                ;栈段结尾置入0,方便后续结束循环
  34.                        
  35.                        
  36.         s0:                div bx                                ;ax为商,dx为余数且必定小于10
  37.                         add dl,30h                        ;将余数转化为十进制字符,8位
  38.                         push dx                                ;将十进制字符压入栈,8位
  39.                         mov dx,0
  40.                        
  41.                         mov cx,ax                        ;将商置入cx,检查cx是否为零,余数为零则跳出循环
  42.                         jcxz s1                               
  43.                         jmp short s0                ;子程序,将十六进制数转化为十进制
  44.                        
  45.                        
  46.         s1:                pop [si]
  47.                         mov cx,[si]                        ;字符串置入数据段,数据为0时,跳出循环
  48.                         inc si       
  49.                        
  50.                         jcxz ok0                       
  51.                         jmp short s1                ;子程序,将十进制字符串置入数据段ds
  52.                        
  53.                        
  54.         ok0:        pop bx
  55.                         pop si
  56.                         pop ax
  57.                         pop cx
  58.                         pop dx                                ;将原始数据送回原寄存器
  59.                         ret                ;将二进制信息转变为十进制字符串,子程序结束
  60.                        
  61.                        
  62. show_str:        ;字符串显示,子程序开始
  63.                         push cx                               
  64.                         push si                                ;程序开始,cx、si压栈,保存主程序数据以及颜色属性
  65.                        
  66.                         mov ax,0b800h
  67.                         mov es,ax                        ;定义字符串目标段地址
  68.                        
  69.                         mov al,160
  70.                         dec dh                                ;地址从零开始计算,所以减一
  71.                         mul dh                               
  72.                         mov bx,ax                        ;计算目标地址偏移行数所占字节数
  73.                         mov al,2
  74.                         mul dl                               
  75.                         sub ax,2                        ;地址从零开始计算,减一,偶数字节存放字符,再减一
  76.                         add ax,bx                        ;计算目标地址偏移列数所占字节数,加上偏移行数所占字节
  77.                         mov di,ax                        ;设置字符串目标偏移地址,获得目标首地址
  78.                                        
  79.                         mov al,cl                        ;保存颜色属性,因为后面需要跳转结束程序需要用cx
  80.                        
  81.                 s:        mov ch,0
  82.                         mov cl,[si]                        ;ds:[si]指向字符串,判断是否可以结束循环
  83.                         jcxz ok                                ;指向结尾0时,跳转结束程序
  84.                        
  85.                         mov es:[di],cl                ;将data中的字符串送入目标地址                       
  86.                         mov es:[di+1],al        ;送入颜色属性                                                       
  87.        
  88.                         inc si
  89.                         add di,2                        ;数据源地址+1,目标地址+2,准备下一次循环
  90.                         jmp short s                        ;无条件跳转,回到循环程序开头
  91.                        
  92.                 ok:        pop si
  93.                         pop cx                                ;程序结束,将保存的数据出栈
  94.                        
  95.                         ret                ;字符串显示,子程序结束


  96. code ends
  97. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 19:04 | 显示全部楼层
8086汇编实验十第三题
学习笔记
8086汇编实验十第三题
assume cs:code

data segment

        db 10 dup(0)

data ends


code segment

start:       
                mov ax,12666                        ;定义将要显示的数据
                mov bx,data
                mov ds,bx
                mov si,0
                call dtoc                                ;子程序,将二进制信息转变为十进制字符串
               
                mov dh,8
                mov dl,3
                mov cl,2                                ;定义字符串目标地址行数、列数、颜色属性
                call show_str                        ;子程序,将字符串显示在目标位置
               
                mov ah,00h
                int 16h
               
                mov ax,4c00h
                int 21h
               
               
dtoc:                ;将二进制信息转变为十进制字符串,子程序开始
                        push dx
                        push cx
                        push ax
                        push si
                        push bx                                ;保存原始数据

                        mov bx,10                        ;方便后面数字除10
                        mov dx,0                        ;dx归零,方便后续计算
                        push dx                                ;栈段结尾置入0,方便后续结束循环
                       
                       
        s0:                div bx                                ;ax为商,dx为余数且必定小于10
                        add dl,30h                        ;将余数转化为十进制字符,8位
                        push dx                                ;将十进制字符压入栈,8位
                        mov dx,0
                       
                        mov cx,ax                        ;将商置入cx,检查cx是否为零,余数为零则跳出循环
                        jcxz s1                               
                        jmp short s0                ;子程序,将十六进制数转化为十进制
                       
                       
        s1:                pop
                        mov cx,                        ;字符串置入数据段,数据为0时,跳出循环
                        inc si       
                       
                        jcxz ok0                       
                        jmp short s1                ;子程序,将十进制字符串置入数据段ds
                       
                       
        ok0:        pop bx
                        pop si
                        pop ax
                        pop cx
                        pop dx                                ;将原始数据送回原寄存器
                        ret                ;将二进制信息转变为十进制字符串,子程序结束
                       
                       
show_str:        ;字符串显示,子程序开始
                        push cx                               
                        push si                                ;程序开始,cx、si压栈,保存主程序数据以及颜色属性
                       
                        mov ax,0b800h
                        mov es,ax                        ;定义字符串目标段地址
                       
                        mov al,160
                        dec dh                                ;地址从零开始计算,所以减一
                        mul dh                               
                        mov bx,ax                        ;计算目标地址偏移行数所占字节数
                        mov al,2
                        mul dl                               
                        sub ax,2                        ;地址从零开始计算,减一,偶数字节存放字符,再减一
                        add ax,bx                        ;计算目标地址偏移列数所占字节数,加上偏移行数所占字节
                        mov di,ax                        ;设置字符串目标偏移地址,获得目标首地址
                                       
                        mov al,cl                        ;保存颜色属性,因为后面需要跳转结束程序需要用cx
                       
                s:        mov ch,0
                        mov cl,                        ;ds:指向字符串,判断是否可以结束循环
                        jcxz ok                                ;指向结尾0时,跳转结束程序
                       
                        mov es:,cl                ;将data中的字符串送入目标地址                       
                        mov es:,al        ;送入颜色属性                                                       
       
                        inc si
                        add di,2                        ;数据源地址+1,目标地址+2,准备下一次循环
                        jmp short s                        ;无条件跳转,回到循环程序开头
                       
                ok:        pop si
                        pop cx                                ;程序结束,将保存的数据出栈
                       
                        ret                ;字符串显示,子程序结束


code ends
end start


你好!你的代码思路基本正确,但在 dtocshow_str 子程序中有几处指令不完整,缺少操作数。下面我为你指出问题并提供修正后的代码。

主要问题:
1. 在 dtocs1 标签处,pop 指令需要指定寄存器(如 dx),且 mov cx, 需要操作数来检查弹出的值。
2. 在 show_strs 标签处,mov cl, 需要从数据段读取字符,且 mov es:,clmov es:,al 需要指定目标偏移地址(如 es:[di])。

修正后的完整代码如下:

  1. assume cs:code

  2. data segment
  3.     db 10 dup(0)
  4. data ends

  5. code segment
  6. start:
  7.     mov ax, 12666          ; 要转换的数字
  8.     mov bx, data
  9.     mov ds, bx
  10.     mov si, 0
  11.     call dtoc              ; 调用转换子程序

  12.     mov dh, 8              ; 行号(1-based)
  13.     mov dl, 3              ; 列号(1-based)
  14.     mov cl, 2              ; 颜色属性(绿色)
  15.     call show_str          ; 调用显示子程序

  16.     mov ah, 00h            ; 等待按键
  17.     int 16h

  18.     mov ax, 4c00h          ; 退出程序
  19.     int 21h

  20. ; 子程序:dtoc
  21. ; 功能:将word型数据转换为十进制字符串,字符串以0结尾
  22. ; 参数:ax = 要转换的数字,ds:si 指向字符串存储区
  23. dtoc:
  24.     push dx
  25.     push cx
  26.     push ax
  27.     push si
  28.     push bx                ; 保存寄存器

  29.     mov bx, 10             ; 除数10
  30.     mov dx, 0              ; 清除dx,用于除法
  31.     push dx                ; 压入0作为字符串结束标志

  32. s0:
  33.     div bx                 ; ax = 商,dx = 余数
  34.     add dl, 30h            ; 余数转换为ASCII码
  35.     push dx                ; 压入ASCII码
  36.     mov dx, 0              ; 清除dx,为下一次除法准备
  37.     mov cx, ax             ; 检查商是否为0
  38.     jcxz s1                ; 如果商为0,跳转到s1
  39.     jmp short s0           ; 继续循环

  40. s1:
  41.     pop dx                 ; 弹出ASCII码到dx
  42.     mov [si], dl           ; 存入数据段
  43.     inc si                 ; 指向下一个字节
  44.     mov cx, dx             ; 检查dx是否为0(结束标志)
  45.     jcxz ok0               ; 如果为0,结束循环
  46.     jmp short s1           ; 继续弹出

  47. ok0:
  48.     pop bx
  49.     pop si
  50.     pop ax
  51.     pop cx
  52.     pop dx                 ; 恢复寄存器
  53.     ret

  54. ; 子程序:show_str
  55. ; 功能:在指定位置显示字符串
  56. ; 参数:dh = 行号(1-25),dl = 列号(1-80),cl = 颜色属性,ds:si 指向字符串首地址
  57. show_str:
  58.     push cx
  59.     push si                ; 保存寄存器

  60.     mov ax, 0b800h
  61.     mov es, ax             ; 设置显存段地址

  62.     ; 计算行偏移:偏移 = (行号 - 1) * 160
  63.     mov al, 160
  64.     dec dh                 ; 行号转换为0-based
  65.     mul dh                 ; ax = dh * 160
  66.     mov bx, ax             ; 保存行偏移

  67.     ; 计算列偏移:偏移 = (列号 - 1) * 2
  68.     mov al, 2
  69.     mul dl                 ; ax = dl * 2
  70.     sub ax, 2              ; 转换为0-based列偏移
  71.     add ax, bx             ; 加上行偏移,得到总偏移
  72.     mov di, ax             ; di 指向显存中的目标位置

  73.     mov al, cl             ; 保存颜色属性到al

  74. s:
  75.     mov ch, 0
  76.     mov cl, [si]           ; 读取字符到cl
  77.     jcxz ok                ; 如果字符为0,结束循环
  78.     mov es:[di], cl        ; 写入字符到显存
  79.     mov es:[di+1], al      ; 写入颜色属性到显存
  80.     inc si                 ; 指向下一个字符
  81.     add di, 2              ; 指向下一个显存位置(字符+属性)
  82.     jmp short s

  83. ok:
  84.     pop si
  85.     pop cx                 ; 恢复寄存器
  86.     ret

  87. code ends
  88. end start
复制代码


关键修正说明:
1. dtoc 子程序中:
   - s1: pop dx:弹出ASCII码到dx。
   - mov [si], dl:将ASCII码存入数据段(只取低8位)。
   - mov cx, dx:检查dx是否为0(结束标志)。
2. show_str 子程序中:
   - mov cl, [si]:从数据段读取字符。
   - mov es:[di], clmov es:[di+1], al:正确写入字符和属性到显存。

这样,程序就能正确将12666转换为字符串"12666"并显示在屏幕第8行第3列了。如果有任何疑问,欢迎继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-3-26 02:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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