erh 发表于 2017-6-21 10:39:31

显示数据段中的数

;----显示数据段中的数----
assume cs:code,ds:data,ss:stack

data segment
        dw 1230,34666,1,2,8,89,1,0ffffh
        db 40h dup(?)
data ends

stack segment
        dw 10h dup(0)
stack ends

code segment
        start:
        mov ax,data
        mov ds,ax
        mov ax,stack
        mov ss,ax
        mov sp,10h
       
        call dtoc
       
       
               ;------准备显示参数------------
        mov ax,10h                        ;第一个处理好的数据的地址
        add si,ax
        mov cl,02h          ;显示的颜色。这里是绿色
        mov dh,16
        mov dl,59         ;注释:dl只能取单数,1表示从第一列显示,3表示从第二列显示...159表示从第80
                            ;列开始显示即是(dl+1)/2,取偶数将出现乱码:-)
        call show_str
       
       
        mov ax,4c00h
        int 21h
       
        dtoc:
               
                push si
                push ax
                push cx
               
                sub si,si                ;读数据段数据的offset address
                mov di,10h                ;写第一个数据的offset address
                               
                rec:
                mov ax,                ;取一个数据
                mov cx,ax       ;放入cx
                sub cx,0ffffh        ;若取到的字是0ffffh,结束
                jcxz endd       ;
               
               
                call trans
               
                add si,2                ;下一个数据位置
                jmp short rec
                endd:         ;
                inc di          ;
                inc di          ;
                sub ax,ax       ;
                mov ,ax                ;;最后一个数据后放一个结束标志0.供show_str函数用
                pop cx
                pop ax
                pop si
        ret
               
        trans:   ;---------转换一个数并放入内存中----------------------
                   push ax
                   push bx
                   push cx
                   push dx
                   push si
                  
                  
                   rmod:;--------循环取余数------------------------
                        ;DIVDW 的参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,
                        ;      (cx)=除数
                        ;返回:(dx)=结果的高16位,(ax)=结果的低16位。(cx)=余数
                   mov cx,0ah                ;除数传传入CX,低16位被除数在AX中
                   sub dx,dx                ;被除数高位是0
                  
                   call divdw                 ;做除法.商在Ax,余数在cx中
                  
                   add cx,30h                ;转换成ascii吗
                   push cx                        ;入栈
                   inc bx                        ;计数入栈数据的数量
                  
                   mov cx,ax                ;商放CX中等待检查
                   jcxz endt                ;商为零跳出
                                     
                   jmp short rmod
                  endt:
                        mov cx,bx
                        spop:
                        pop                 ;顺序将数据出栈,并存入内存
                        add di,2
                        loop spop
                       
                        mov ax,2020h        ;每个数据中间插入2个空格
                        mov ,ax
                        inc di
                        inc di                        ;下一个存储数据位置
                       
                  pop si
                  pop dx
                  pop cx
                  pop bx
                  pop ax
        ret
                  
        ;注解:DIV CX;--商在AX中,余数在DX中 ;   DIV BL;商在AL中,余数在AH中           
        divdw:
                push si
                push ds
                push bx
               
                sub si,si       ;数据暂存位置
                mov bx,ax                ;被除数低16位存放到bx
                mov ax,dx                ;高16位放入ax,准备除法
                sub dx,dx                ;高16位清零
                div cx                        ;H/N
                push ax                        ;高16位除法后的商 入栈
                               
                mov ax,bx               ;低16位数放ax中。因为余数在DX中,会直接参与低位除法的运算,
                               
                div cx                       ;相当于[(余数 X 10000H)+ 低16位数] ÷ 除数。注:----商在AX中
               
                mov cx,dx               ;余数存入cx--over
                pop dx         ;高位商存入dx
               
                pop bx       
                pop ds
                pop si
        ret
       
        ;名称:show_str。功能:指定的位置,显示一个用0结束的字符串
        ;参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),(cl)=颜色,
        ;       ds:si指向字符串首地址
        show_str:
                push si
                push di
                push es
                push ax
                push bx
                push cx
                push dx
               
                call cls
               
                mov ax,0b800h      
      mov es,ax         ;显示缓存段地址
          dec dh
          dec dl
          mov al,0a0h
          mul dh            ;显示的行地址
          sub dh,dh
          add ax,dx         ;行+列的地址
          mov di,ax         ;显示线性地址放di
                mov bl,cl         ;因为后面要检测cx值,所以将cl暂存bl
                 
                s0:
                mov cl,bl
                mov ch,ds:       ;要显示的字符
                mov es:,ch       ;显示的字符放对应显示缓存的低字节
                mov es:,cl   ;显示的属性放对应显示缓存的高字节
                inc        si
                inc si                             ;下一个要显示的字符
                add di,2             ;下一个要显示缓存地址
               
                sub cl,cl
                jcxz ok
                jmp short s0
                ok: pop dx
                        pop cx
                        pop bx
                        pop ax
                        pop es
                        pop di
                        pop si
        ret
               
                  
        cls:
                   push ax
                   push cx
                   push es
                   push si
                   mov cx,3840
                   mov ax,0b800h
                   mov es,ax
                   sub si,si
                   sc:mov ax,3000h
                     mov es:,ax
                     inc si
                       inc si
                       loop sc
                   pop si
                   pop es
                   pop cx
                   pop ax
        ret
       
       
code ends
end start


调试拍错真{:10_260:} 的难,做好注释很重要{:10_261:}
页: [1]
查看完整版本: 显示数据段中的数