0

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?

3
  • Which assembler are you using, and which OS are you targetting? Commented Jun 29, 2013 at 20:47
  • I'm programming on emu8086 emu86.com I think it compiles for intel8086 processor, I think it virtualizes DOS Commented Jun 29, 2013 at 20:48
  • What does the emu8086 documentation say about it? On quick look, emu8086 seems fairly bare bones to me. What you're showing looks like a printf-like library that would be needed. Someone may have written one and posted it somewhere, but I couldn't find one with a perfunctory search. Just simpler stuff. Commented Jun 29, 2013 at 21:22

1 Answer 1

1

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.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.