宏打印存储在字节中的值。组装masm

Posted

技术标签:

【中文标题】宏打印存储在字节中的值。组装masm【英文标题】:Macro printing a value stored in a byte. Assembly masm 【发布时间】:2017-03-24 07:06:15 【问题描述】:

组装,masm

嘿,我写了一个宏,它打印存储在 dane1 段中的 1 字节值。

我将该值除以 16,然后将提醒推送到堆栈,直到 value==0。然后我弹出提醒将它们转换为 ASCII 码,然后打印出来。

有人看我的代码吗?我应该改变什么以使其更简单?

我不想每次都这样做:

mov dl,67h
mov ds:[v1],dl
print v1

是否可以修改这个宏,以便它可以使用它:

print 67h
print al

感谢您的帮助。

assume  cs:code1
.186

dane1   segment
v1 dw 0D9h    ;to use macro
dane1   ends

print macro value
    pusha
    mov ax,seg value
    mov ds,ax
    mov ax,ds:[value]
    xor cx,cx        ;CX - repetitions
    analyse:         ;pushes the digits into stack
        mov dl,16    ;divisor
        div dl                 ;divide number in AX by 16   
        xor dx,dx
        mov  dl,ah ;remainder into the stack   
        push dx 
        xor ah,ah ;        prepare quotient for next loop       
        inc cx               ;increase repetitions    
        cmp ax,0             ;break condition
        jne analyse    
    begin1:                 ;print character stored in the stack
        pop dx              ;pop to DL
        cmp dl,10d          ;is DL digit or char
        jb digit                         
            char:            ;convert to ASCII 
                add dl,55
                jmp begin2  
            digit:
                add dl,'0'
                jmp begin2  
         begin2:
         mov ah,2           ;print character converted to ASCII 
         int 21h
         loop begin1
    popa
endm 

code1   segment

start1: mov ax,seg top1
    mov ss,ax
    mov sp,offset top1 

    print v1

mov ah,4ch
int 21h

code1   ends



stos1   segment stack
    dw  200 dup(?)
top1    dw  ?
stos1   ends

end start1      

【问题讨论】:

为什么不使用寄存器来打印值? div 很慢。 AX / 16 的提醒,例如可以用AND AX,0Fh计算,结果是SHR AX,4 如果你只想显示字节值,你的十六进制数字总是最多只有 2 位 【参考方案1】:

对于较新的 MASM(版本 >= 6),您可以使用 TYPE 指令为 8 位寄存器创建特殊条件。另外,看看我的改进:

.MODEL small
.386

.STACK
.DATA

.CODE

print_num MACRO value
LOCAL analyse, write, show
    pusha

    IF TYPE(value) eq 1         ; 8-bit register
        movzx ax, value
    ELSE
        mov ax, value
    ENDIF

    xor cx, cx          ; repetitions
    mov bx, 16          ; divisor

    analyse:            ; First step: push the digits into stack
        xor dx, dx      ; Clear DX for division
        div bx          ; DX:AX/BX = AX remainder DX
        push dx
        inc cx
        cmp ax, 0       ; break condition
        jne analyse

    write:              ; Second step: pop the digits from stack and print
        pop dx          ; Only DL is needed
        add dl, "0"
        cmp dl, "9"     ; Is DL digit?
        jbe SHORT show  ; Yes: skip the next line
        add dl, 7       ; Adjust ASCII
        show:
        mov ah, 2       ; Print character to STDOUT
        int 21h
        loop write

    popa
ENDM

Linefeed MACRO
    pusha
    mov ah, 2
    mov dl, 0Dh          ; CR = carriage return
    int 21h
    mov dl, 0Ah          ; LF = line feed
    int 21h
    popa
ENDM

main PROC
    mov ax, @data
    mov ds, ax

    mov ax, 1234h
    print_num ax
    Linefeed

    print_num al
    Linefeed

    print_num 126

    mov ax, 4C00h
    int 21h
main ENDP

END main

【讨论】:

edit ": LF = 换行" "; LF = 换行" 分号 @NowakGrzegorz:真丢脸!谢谢。 :-) 是否有替代方案:“IF TYPE(value) eq 1”指令?它对我不起作用:(我在哪里可以找到有关它的信息? @NowakGrzegorz:不是那种简单的方式。你的 MASM 太旧了。您可以创建两个(几乎相同的)宏,一个用于 8 位值,一个用于 16 位值。我建议下载 JWASM (sourceforge.net/projects/jwasm/files/?source=navbar)。如果您使用 DOSbox,您可以使用“DOS 二进制文件”。

以上是关于宏打印存储在字节中的值。组装masm的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 WinApi 的 WriteConsole 打印 LOCAL 字节

java GBK中,是如何将两个字节,组装成一个汉字的

在 MASM 程序集中逐字节循环和处理字符串

如何在程序集的循环内打印字符串(MASM)

在 win32 上用 MASM 组装的程序没有控制台输出

Arduino UNO + DS1302利用31字节静态RAM存储数据并串口打印