Question

I have variable like this one:

myVar db 'A','B',0

I need to embed 'A' and 'B' in the middle of a string that is printed on screen. Something like this:

CALL PTHIS
db 'first val is ', %1, ' second val is ', %2, 0

I think I saw something like this somewhere. How can this be done?

No correct solution

OTHER TIPS

For the sake of an answer I wrote a very simple printf parser. It works like its big brother of C, but understands only the format specifier '%c' and '%s'. This can be expanded as well.

It's also a good example to explore the C calling convention.

Following program assembles in EMU8086, TASM, JWASM and MASM>=6.0:

.MODEL tiny                     ; For MASM 6 and TASM
.CODE                           ; For MASM 6 and TASM
.186                            ; For MASM 6 (push immediates)
ORG 100h                        ; Origin for COM program


start:
                                ; printf (&format, &myVar, myVar[0], myVar[1])
    push WORD PTR myVar + 1     ; Forth argument (single character directly pushed)
    push WORD PTR myVar + 0     ; Third argument (single character directly pushed)
    push OFFSET myVar           ; Second argument (address of null terminated string)
    push OFFSET fmt             ; First argument (address of null terminated format string)
    call printf
    add sp, 2 * 4               ; Adjust stack: 4 arguments a 2 bytes

    lea dx, report
    mov ah, 09h
    int 21h

    RET                         ; return to operating system.


printf PROC
        push bp                 ; Prologue
        mov bp, sp
        sub sp, 2 * 3           ; Reserve local stack for three WORDs
        mov [bp-2], bx          ; Preserve BX (CCall calling convention)
        mov [bp-4], si          ; Preserve SI (CCall calling convention)
        mov [bp-6], di          ; Preserve DI (CCall calling convention)

        mov di, 4               ; Counter to the arguments
        mov si, [bp+di]         ; Get the first argument
    output:
        mov ax, [si]            ; Get two characters
        cmp al, '%'             ; First charcter == '%'
        jnz J1                  ; No, skip over the placeholder blocks

        cmp ah, 'c'             ; Second character == 'c'
        jnz no_c                ; No, skip over the '%c' placeholder block
        inc si                  ; Adjust the index to format string
        add di, 2               ; Point to the next argument on stack
        mov al, BYTE PTR [bp+di]    ; Get the argument (it is a directly pushed character)
        jmp J1                      ; and print it
    no_c:

        cmp ah, 's'             ; Second character = 's'
        jnz no_s                ; No skip over the %s placeholder block
        add si, 2               ; Adjust the index to format string
        add di, 2               ; Point to the next argument on stack
        mov bx, [bp+di]         ; Get argument (it is an offset to an ASCIIZ string)
    next:
        mov al, [bx]            ; Get character
        test al, al             ; character == 0
        jz output               ; Yes - this string is ready, turn back to format string
        mov ah, 0Eh             ; Teletype
        int 10h                 ; BIOS
        inc bx                  ; Point to next charcter
        jmp next                ; Repeat the output
    no_s:

    J1:
        test al, al             ; Character == 0?
        jz ready                ; Yes, format string is ready, print is done

    doit:
        mov ah, 0Eh             ; Teletype
        int 10h                 ; BIOS
        inc si                  ; Point to next character
        jmp output              ; Repeat the bunch

    ready:
        mov bx, [bp-2]          ; Restore BX (CCall calling convention)
        mov si, [bp-4]          ; Restore SI (CCall calling convention)
        mov di, [bp-6]          ; Restore DI (CCall calling convention)
        mov sp, bp              ; Epilogue
        pop bp
        ret
printf ENDP

fmt     db "From the word %s is the first char %c and the second char %c",0
myVar   db 'H','e','l','l','o',0
report  db 13,10,13,10,"I'm back to the root",13, 10,'$'

END start                       ; Directive to stop the compiler.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top