Author Topic: How to see register contents via MASM  (Read 8829 times)

uKw

  • Guest
How to see register contents via MASM
« on: June 09, 2012, 03:18:42 PM »
Hello, i am a newbie in assembly programming. I am using MASM (academic reference).
Things i can do :

01. Write ASM file.
02. Create OBJ file through MASM.
03. Create EXE file through Linker.
04. Create BIN file through Exe2bin.
05. Create HEX file through Bin2hex.

I want to see what is the register contents (AX,BX, etc) after compiling my program in Command Prompt.

But i don't know how to do it. I am stopped after creating hex file.

Can anyone help me?

dedndave

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: How to see register contents via MASM
« Reply #1 on: June 09, 2012, 03:30:26 PM »
ok - this is 16-bit code - we have a sub-forum for that

anyways...
the register contents are binary
so, you need a routine to convert them to ASCII decimal or ASCII hex
then, you can use INT 21h, function 9 to display them

here is a program that is written to create an EXE (not COM) file
it has 4 subroutines that you can use for various things and a main program that uses them...
Code: [Select]
;Even Numbers - DednDave, 3-2012

        .MODEL  Small
        .DOSSEG                     ;DOS segment order
        .STACK  1024
        OPTION  CaseMap:None        ;case sensitive

;####################################################################

;equate(s)

BUFSIZE EQU 5                       ;user input buffer size, 255 max

;####################################################################

;structure(s)

INBUFFER  STRUCT
  MaxBytes  db ?
  UsedBytes db ?
  Buffer    db BUFSIZE+1 dup(?)
INBUFFER  ENDS

;####################################################################

        .DATA

s$Prompt1 db 'Enter a Number: ',24h
s$ErrMsg1 db 'Non-Numeric Character in String',24h
s$ErrMsg2 db 'Value Too Large',24h
s$AnyKey  db 0Dh,0Ah,'Press Any Key To Exit',24h
s$CrLf    db 0Dh,0Ah,24h

OutBuf    db 5 dup(?),24h

;********************************************************************

        .DATA?

InpBuf  INBUFFER <>

;####################################################################

        .CODE

;********************************************************************

_main   PROC    FAR

;------------------------------------------

;set DS to DGROUP

        ASSUME  DS:DGROUP

        mov     ax,@data
        mov     ds,ax

;------------------------------------------

;initialize input buffer size

        mov    InpBuf.MaxBytes,BUFSIZE+1

;------------------------------------------

;get user input value

Input0: call    NewLine
        mov     dx,offset s$Prompt1 ;'Enter a Number:'
        call    PrInp

;------------------------------------------

;display even numbers from 0 to <UserValue>

        mov     bx,dx
        xor     ax,ax

Evens0: call    UnsDec
        call    StrOut
        add     ax,2
        jc      Exit00

        cmp     ax,bx
        jbe     Evens0

;------------------------------------------

;wait for a key press

Exit00: mov     dx,offset s$AnyKey  ;'Press Any Key To Exit'
        call    StrOut
        mov     ah,1                ;wait for key
        int     16h                 ;BIOS keyboard call
        mov     ah,0                ;get keyboard character
        int     16h                 ;BIOS keyboard call

;------------------------------------------

;terminate program

        mov     ax,4C00h            ;terminate, return = 0
        int     21h                 ;DOS function call

_main   ENDP

;********************************************************************

NewLine PROC    NEAR
;
;Display a Carriage Return/Line Feed
;
;Call With: Nothing
;
;  Returns: Nothing
;
;     Uses: all registers are preserved
;
;------------------------------------------

        push    dx
        push    ax
        mov     dx,offset s$CrLf
        mov     ah,9
        int     21h
        pop     ax
        pop     dx
        ret

NewLine ENDP

;********************************************************************

StrOut  PROC    NEAR
;
;Display a String Followed by Carriage Return/Line Feed
;
;Call With: DX = address of string to display
;
;  Returns: Nothing
;
;     Uses: all registers are preserved
;
;------------------------------------------

        push    ax
        mov     ah,9
        int     21h
        call    NewLine
        pop     ax
        ret

StrOut  ENDP

;********************************************************************

PrInp   PROC    NEAR
;
;Get 16-Bit Unsigned User Input With Prompt And Retry Error Handling
;
;Call With: DX = address of prompt string to display
;
;  Returns: DX = unsigned integer entered by user
;
;Also Uses: all other registers are preserved
;           the "InpBuf" buffer is used to hold the string
;
;------------------------------------------

        push    ax
        push    bx
        push    cx
        push    si

PrInp0: push    dx
        mov     ah,9
        int     21h
        mov     dx,offset InpBuf
        mov     ah,0Ah
        int     21h
        call    NewLine
        xor     dx,dx
        mov     cl,InpBuf.UsedBytes
        mov     ch,dl
        mov     si,offset InpBuf.Buffer
        mov     ah,dl

PrInp1: lodsb
        xor     al,30h
        cmp     al,9
        ja      PrInp2

        cmp     dx,6553
        ja      PrInp4

        shl     dx,1
        mov     bx,dx
        shl     dx,1
        shl     dx,1
        add     dx,bx
        add     dx,ax
        jc      PrInp4

        loop    PrInp1

        pop     ax                  ;discard string pointer
        pop     si                  ;restore registers
        pop     cx
        pop     bx
        pop     ax
        ret

PrInp2: mov     dx,offset s$ErrMsg1 ;'Non-Numeric Character in String'

PrInp3: call    StrOut
        pop     dx
        jmp     PrInp0

PrInp4: mov     dx,offset s$ErrMsg2 ;'Value Too Large'
        jmp     PrInp3

PrInp   ENDP

;********************************************************************

UnsDec  PROC    NEAR
;
;Convert a 16-Bit Unsigned Integer to ASCII Decimal String
;
;Call With: AX = unsigned binary integer
;
;  Returns: DX = address of '$'-terminated ASCII decimal string
;           CX = length of ASCII decimal string
;
;Also Uses: all other registers are preserved
;           the "OutBuf" buffer is used to hold the string
;
;------------------------------------------

        push    di
        push    bx
        push    ax
        mov     di,offset OutBuf+sizeof OutBuf-1
        mov     bx,10               ;BX = divisor
        push    di

UnDec0: xor     dx,dx               ;zero the high word
        dec     di                  ;point to next string byte
        div     bx                  ;divide DX:AX by 10
        or      dl,30h              ;set ASCII bits in remainder
        mov     [di],dl             ;store the numeric character
        or      ax,ax               ;any quotient left ?
        jnz     UnDec0              ;loop until done

        pop     cx
        mov     dx,di               ;DX = address of first char
        sub     cx,di               ;CX = string length
        pop     ax
        pop     bx
        pop     di
        ret

UnsDec  ENDP

;####################################################################

        END     _main

jj2007

  • Member
  • *****
  • Posts: 7542
  • Assembler is fun ;-)
    • MasmBasic
Re: How to see register contents via MASM
« Reply #2 on: June 09, 2012, 03:49:19 PM »
First, welcome to the Forum :icon14:

Second, unless you have a really, really convincing reason (such as your teacher being a dinosaur), drop that 16-bit thing and go for 32-bit code.

Third, to see registers in action, you have two choices:
1. a debugger such as OllyDbg
2. or a debugging macro such as deb:

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init
   mov eax, 1234567
   cdq
   mov ecx, 1000
   mul ecx
   deb 4, "After first multiplication:", eax, edx, ecx
   mul ecx
   deb 4, "After second multiplication:", eax, edx, ecx
   div ecx
   deb 4, "After first division:", eax, edx, ecx
   div ecx
   deb 4, "After second division:", eax, edx, ecx
   Inkey "ok"
   Exit
end start

Code: [Select]
After first multiplication:
eax             1234567000
edx             0
ecx             1000

After second multiplication:
eax             1911386048
edx             287
ecx             1000

After first division:
eax             1234567000
edx             0
ecx             1000

After second division:
eax             1234567
edx             0
ecx             1000

Is that what you want to see?

A good debugging macro preserves all registers and flags and thus allows you to see exactly what your code does.
Note the snippet above needs to be assembled as "console assembly and link", and you need either JWasm or Masm 6.15 or higher.

Perhaps you should explain a little bit more what you are doing and why, so that we can point you to the right literature.

Farabi

  • Member
  • ****
  • Posts: 970
  • Neuroscience Fans
Re: How to see register contents via MASM
« Reply #3 on: June 09, 2012, 09:28:49 PM »
Or, you can use IDA Pro or OllyDbg. It is somekind of virtual machine that run 32-bit program and aid you to check each code you wrote.
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165