简体   繁体   中英

Pass parameters by adress to Macros in Assembly 8086 MASM

I have a macro to read user input using Interrupt Int 21,A. I want to pass the adress of variable 'parcela1' by argument so i can modify it inside the macro. Printing parcela1 (at the end of the program) prints 2 lines of random chars and 00000000, where it should be the chars entered. I'm not sure what is wrong, can you help me please?

.8086
.model small
.stack 2048

dseg segment para public 'data'
    parcela1    db '00000000$'      ;Var to pass by address.
    InputBuffer db 9,0,8 dup(0),13
dseg ends

cseg segment para public 'code'
assume cs:cseg, ds:dseg

ReadInput MACRO UserInput, maxchar, minchar, x,y

    LOCAL READ_DATA,COPY_DATA

    pushf
    push ax 
    push bx
    push cx
    push dx
    push si

    mov ah,02h              ;position cursor at x,y.
    mov bh,0
    mov dl,x
    mov dh,y
    int 10h

    mov al,maxchar          ;Max number of chars to read.
    add al,1                ;maxchar + 1 (1 for CR).
    mov inputBuffer[0],al
    mov bl,minchar

    mov ah,0Ah              ;INT 21,A - Buffered Keyboard Input.

READ_DATA:
    lea dx,InputBuffer
    int 21h
    cmp InputBuffer[1],bl   ;If chars read < minchar repeat.
    jb  READ_DATA

    xor bx,bx
    mov bl,InputBuffer[1]   ;store num chars read in BL.

    mov cx,bx               ;Loop CX.

    mov si,bx               ;SI - index of last char read in InputBuffer. 
    inc si

    xor bx,bx               ;DI - index of last position of UserInput.
    mov bl,maxchar
    dec bl

COPY_DATA:                  ;copy chars read to parcela1.
    mov al,InputBuffer[si]
    mov [UserInput+bx],al
    dec si
    dec bx
    loop COPY_DATA

    pop si
    pop dx
    pop cx
    pop bx 
    pop ax
    popf
ENDM

Main proc
    mov ax, dseg
    mov ds, ax

    lea si,parcela1         ;Pointer to start of vector.
    ReadInput si,8,1,0,0    ;macro ReadInput 

    lea dx,parcela1         ;print parcela1
    mov ah,09h
    int 21h

    mov ah,08h              ;pause.
    int 21h

ENDPROG:
    mov ah,4ch
    int 21h
Main endp
cseg ends
end Main

At least you forgot

mov ax, dseg
mov ds, ax

at the beginning of your main procedure. ASSUME is not enough.

The second error applies the macro.

ReadInput si,8,1,0,0 ;macro ReadInput

is a text substitution rule for a substitution at assembling time. You cannot pass a computed value to a macro. Hence, when the assembler reaches

mov [UserInput+bx],al

it substitutes it to

mov [si+bx],al

Since SI has changed inside the macro you'll get the wrong pointer and AL will be stored elsewhere. If you need to pass arguments which will be computed at runtime you have to create a procedure.

The third error is a deep misunderstanding of structure and use of InputBuffer. Please read a reference to INT 21h/0Ah , eg http://www.ctyme.com/intr/rb-2563.htm . Consider also the different end-of-string characters of the buffer in INT 21h/0Ah and of the buffer in INT 21h/09h .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM