Feb 10, 2011

Assembly macro - Some useful stuffs

Hello :)

After running through the nuisance of printing output and debugging, I have came up with these macro. It might be useful for you somehow :)

All bug free :) I hope the code is self-explained. But if there are any errors or things you want to add, please leave a comments :)

    ;useful macro call
    ;make new line: printChar 10 printChar 13
    ;add a break point in your code that stop TurboDebugger when you hit F9: addBreakPoint

    addBreakPoint macro
        ;save register
        push AX
  
        pushf                                                        ;AX=PSW
        pop AX                                                   ;
       
        or AX,0100h                                           ;set 8th bit (trap flag)
       
        push AX                                                  ;PSW=AX
        popf                                                         ;
       
        ;restore register
        pop AX
    endm

    printChar macro    character                        ;print a character
    ;save register
        push DX
        push AX
                   
        mov DL, character                                    ;
        mov AH, 02h                                    ;
        int 21h                                        ;
       
        ;restore register
        pop AX
        pop DX
    endm
   
    printMsg macro msgString                        ;print a message
        ;save register
        push DX
        push AX
                                   
        mov DX, offset msgString                    ;print q1_1 string
        mov AH, 09h                                    ;
        int 21h                                        ;           
       
        ;restore register
        pop AX
        pop DX
    endm
Some quick thing to note:
  • I tried doing CMP with 8-bit register and use the "less than" jump command, but it does not turn out as expected. Instead, JL only works when CMP is called for 2 16-bit register.

Feb 8, 2011

Printing integer with assembly

Assembly is really a trouble some language when it comes to performing "thought-to-be-simple" task. Printing an integer is an example.

Having completed the code for that, I hope posting it here will help those who are looking for away to do it :)
The code is not optimized, nevertheless, so you should use it as a reference only.

I made use of the 21, 9 interrupt, which prints a string delimited by the '$' to the screen.


;count the number of digit of a 1-byte integer
;number stored in AX (AL actually, since it's 1-byte)
;count value stored in CX

;convert the number into a string and print out

myStackSeg segment stack      
                    db 128 dup (?)                    ;space for stack
    tos                label word                        ;top of stack
myStackSeg ends


myDataSeg segment  
    _dec_10 db 10                                    ;declare decimal value 10
    intStr    db 4 dup(?)                                ;1-byte integer -> 3 digit max -> 4 space (1 for '$')
    myNumber equ 176
    _eos db '$'
myDataSeg ends


myCodeSeg segment
assume CS:myCodeSeg, DS:myDataSeg, SS: myStackSeg

start:
    ;initialize segment register
    mov    AX,    seg myDataSeg                            ;
    mov    DS,    AX                                        ;initialize DS
    mov AX, seg myStackSeg                            ;
    mov SS, AX                                        ;
    mov SP, offset tos                                ;initialize SS

  
    ;convert the digits into string
    mov DX, myNumber
    mov BX, offset intStr
  
    ;count the number of digit of a number in AX      
    mov AX, DX                                        ;AX store the number
    xor CX, CX                                        ;clear CX
    jmp countDigit                                    ;start counting
  
    nextDigit:                                        ;still got digit remain
        mov AH, 00h                                    ;clear remainder
        jmp countDigit                                ;count again
  
    countDigit:                                        ;count and div 10
        div _dec_10                                    ;div 10; AL=remainder, AH=div result
        inc CX                                        ;at least 1 digit      
        cmp AL, 0                                    ;if (div result)!=0
        jne nextDigit                                ;prepare to count again

    ;CX hold no of digit
    mov DL, CL                                        ;
    add DL, 48                                        ;convert to corresponding ASCII character
    mov AH, 02h                                        ;print character to screen
    int 21h                                            ;
  
    mov DI, BX                                        ;DI=@intPtr (array storing the characters to print)
    add DI, CX                                        ;move DI to end of string (eos)
    mov AH, _eos                                    ;copy the string delimiter '$'
    mov [DI], AH                                    ;to then end of string
    mov AX, myNumber                                ;AX=number to print
    ;jmp convertDigit                                ;start printing
  
    convertDigit:
        div _dec_10                                    ;div 10 AX
        add  AH, 48                                    ;AH=AX mod 10. convert it to ASCII character
        mov [DI], AH                                ;copy the character to its position in the output str
        mov AH, 00h                                    ;clear the character -> AX=AX div 10
        dec DI                                        ;move back 1 space in the output str
        loop convertDigit                            ;loop till all digits are converted
      
    mov DX, BX                                        ;print the converted string
    mov AH, 09h                                        ;
    int 21h                                            ;
  
exit:
    mov AH, 4Ch                                        ;exit
    int 21h                                            ;
myCodeSeg ends
end start