1、要求

2、实现代码(可惜没找到csdn对8086汇编显示方式)

assume cs:code

data segment
    dw 16 dup(0) ;除法的缓存区域
    db 16 dup(0) ;存储字符串转换的结果的缓存区
    dw 123,12666,1,8,3,38  ;入参,需要将这些10进制的数字,在命令行窗口显示出来
data ends

stack segment
    dw 64 dup(0)
stack ends

code segment
start:
    ;;初始化数据区
    mov ax,data
    mov ds,ax
    mov bx,0
    ;;初始化栈区
    mov ax,stack
    mov ss,ax
    mov sp,080h
    ;;准备调用数据
    mov dh,8 ;显示开始的行
    mov dl,3 ;显示开始的列

    mov si,48 ;入参的开始位置
    mov cx,6  ;入参的数量
    s:
        push cx
        push dx
    
        ;;清空输出缓存区
        call cls_buf
        
        ;读取要转换的十进制数字
        mov ax,[si]
        add si,2

        ;转换,并将结果存储在缓存区
        ;mov ax,12666
        mov dh,8 ;显示开始的行
        mov dl,3 ;显示开始的列
        call dtoc
        
        ;;显示结果
        mov cl,2 ;要显示的文字的属性
        pop dx
        call show_str
        inc dh ;换行

        pop cx
        loop s        
    mov ax,4c00h
    int 21h

cls_buf:
    push si
    push cx
    mov si,020h
    mov cx,8
    cls_s:
        mov ax,0
        mov [si],ax
        add si,2
        loop cls_s
    pop cx
    pop si
    ret

dtoc:       
    push si
    mov si,020h
    ;
    mov dx,0
    mov bx,0 ;记录除法的次数
    
    dtoc_s0:
        mov cx,10  ;除数为10
        call divdw
        push cx ;;余数入栈
        mov cx,ax
        or cx,dx ;;dx和ax必须同时为0
        inc bx
        jcxz dtoc_s1
        jmp short dtoc_s0
    
    dtoc_s1:
        mov cx,bx
    dtoc_s2:
        pop ax ;;余数,但由于除数为10,所以只需要al
        add al,48
        mov [si],al
        inc si
        loop dtoc_s2
    pop si
    ret

divdw:  ;高16位除法
        push bx
        mov bx,0
        mov [bx],dx
        mov [bx+2],ax
        mov [bx+4],cx
        
        mov dx,00 ;高16位
        mov ax,[bx] ;低16位
        div cx
        ;ax 商  ;保存结果(1)
        mov [bx+6],ax
        ;dx 余数;参与后续计算
        ;mov dx,dx
        mov ax,[bx+2]
        div cx
        ;ax 商
        mov [bx+8],ax
        ;dx 余数
        mov [bx+10],dx
        ;;;;;;;;;;输出计算结果
        mov dx,[bx+6]
        mov ax,[bx+8]
        mov cx,[bx+10]
        pop bx
        ret

show_str:   
    push ax
    push bx
    push cx
    push dx
    push si
    push di
    push es
    mov si,020h
    ;计算要存放内存的首地址,di
    ;dh*160+dl*2
    mov al,160
    mul dh
    push ax
    mov al,2
    mul dl
    add di,ax
    pop ax
    add di,ax
    ;读取si处的内容,按要求存放到di处
    mov ax,0b800h
    mov es,ax
    ;;;;;;;;;;;;;;;;;;;;;;;;;
            
    show_s0:  
        push cx
        ;cx <- ds:[si]
        ;如果cx为0,结束
        mov ch,0
        mov cl,[si]
        jcxz show_ok
        ;接收 cl->ah, al <= ds:[si]
        ;es:[di] <= ax
        mov ax,cx        
        pop cx
        mov ah,cl
        mov es:[di],ax
        inc si
        add di,2
        jmp short show_s0
    
        ;;
    show_ok: 
        pop cx
        pop es
        pop di
        pop si
        pop dx
        pop cx
        pop bx
        pop ax
    ret

code ends
end start

3、运行效果

汇编练习-1-LMLPHP

4、求教

这是笔者从学习汇编语言以来,目前碰到的最复杂的一个程序,除法(溢出)、模块化调用、受制于寄存器的数量... 笔者自己感觉写得一团糟,尽管结果是正确的。笔者想真心求教下:

1、是否有比较轻量级的汇编IDE,基于8086的,或配套本书的。汇编排错真心难;

2、是否有一些编程规范,模块化或函数化的规范(不同的模块是否可以像高级编程语言一样,分几个文件存储);

3、哪里能看到一些别人写得比较好的汇编代码或工程(但鉴于笔者目前的水平,可能也看不太懂)

11-06 22:06