布衣君 发表于 前天 19:02

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

FishC 发表于 前天 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

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

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

修正后的完整代码如下:

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            ; 行号(1-based)
    mov dl, 3            ; 列号(1-based)
    mov cl, 2            ; 颜色属性(绿色)
    call show_str          ; 调用显示子程序

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

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

; 子程序:dtoc
; 功能:将word型数据转换为十进制字符串,字符串以0结尾
; 参数:ax = 要转换的数字,ds:si 指向字符串存储区
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 = 余数
    add dl, 30h            ; 余数转换为ASCII码
    push dx                ; 压入ASCII码
    mov dx, 0            ; 清除dx,为下一次除法准备
    mov cx, ax             ; 检查商是否为0
    jcxz s1                ; 如果商为0,跳转到s1
    jmp short s0         ; 继续循环

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

ok0:
    pop bx
    pop si
    pop ax
    pop cx
    pop dx               ; 恢复寄存器
    ret

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

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

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

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

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

s:
    mov ch, 0
    mov cl,          ; 读取字符到cl
    jcxz ok                ; 如果字符为0,结束循环
    mov es:, cl      ; 写入字符到显存
    mov es:, al      ; 写入颜色属性到显存
    inc si               ; 指向下一个字符
    add di, 2            ; 指向下一个显存位置(字符+属性)
    jmp short s

ok:
    pop si
    pop cx               ; 恢复寄存器
    ret

code ends
end start

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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 8086汇编实验十第三题