News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Displaying register values

Started by zak100, December 16, 2009, 01:50:25 PM

Previous topic - Next topic

zak100

Hi,
Thanks for your work. I would try this code but right now I am interested in printing the strings only so that I can find what wrong I am doing in that code. I found loadOfs/16 again zero. I have to minus the conversion part to check that error. However you are helping a lot.

Zulfi.

dedndave

if you don't display the register values - you will want to ADD DI,8 instead so the video address is correct
when you add the code to display the register values, take that ADD back out

zak100

Ok. I am trying your code by altering it. After that I would put it on this forum. Actually in my original program I commented the conversion part because if its not printing the strings (2-dimensional regnames array), there is no point of going further.

Zulfi.

dedndave

lol - i was hoping my code would work without modification
try it out for me so i know if it works
i have no floppy drive   :'(

zak100

Hi,
I have not modified your code and its working perfectly alright.

Zulfi.

dedndave

thanks for testing it, Zulfi   :bg

FORTRANS

Hi,

   Late again.  Tested it and it works.

Steve

dedndave


zak100

Hi,
I have tried your program again by commenting the line:


;call    B2Hex

When I execute it as a standalone com file, I am getting garbage string values printed in a zigzag fashion. But when I try to execute this code as a kernel, then I got proper string messages but they are also printed in a zigzag manner.

Kindly tell me the purpose of following statements:

sub word ptr [bp+24],3      ;adjust for 3 byte CALL
add word ptr [bp+22],2      ;adjust for the CALL


Zulfi.


dedndave

the first one...
a near CALL instruction is 3 bytes long
the return address that is pushed onto the stack is for the code immediately following the CALL
we want to display the value of IP at the address before the CALL, so we adjust the IP register value by 3

the second one is similar...
the CALL instruction pushes a word address onto the stack
we want to display the value for the SP register before that was done, so we adjust the SP register value by 2
we could fix this by pushing SP before the CALL, then adjusting the IP value by 4, instead of 3
that would eliminate one of the instructions (IP would then be [BP+22] instead of [BP+24])
we would also have to swap the "sp = " and "ip = " strings, so that SP is displayed last

as i mentioned in a previous post...
if you do not display the 4 hex bytes, you should adjust the DI register by adding 4
that is why the register names are not displayed properly alone
where the CALL B2Hex was removed, put a temporary instruction: ADD DI,4

zak100

Thanks. It would take some time for me to comprehend it.

Zulfi.

dedndave

Zulfi,
  it isn't hard   :P
the CALL instruction simply pushes the code address onto the stack where the RET instruction should resume execution

        CALL    MyProc
ResumeAddress:
;       next instruction
.
.
MyProc  PROC    NEAR

        RET

MyProc  ENDP

in this example, CALL pushes the address of ResumeAddress onto the stack and jumps to MyProc
when MyProc is done, the RET instruction pops that address back off the stack and into the IP register

for what we want to do, we just need the address
since there is no "PUSH IP" instruction, we use CALL instead
the near CALL instruction is 3 bytes long
what we want to display is the address of the CALL - not the address of ResumeAddress, so we subtract 3

after that, we push the SP register, but it is off by 2, because the CALL used 2 bytes of stack space
we want to display the SP register contents prior to the CALL, so we add 2

in the ShowR program i attached in the previous post, i used a FAR CALL so that the routine may be used from
other code segments and will report the CS that it was called from
the CALL FAR instruction is 5 bytes long and pushes both CS and IP

zak100

Ok, i got it. Actually in  my prog , it was using SP and we were doing  pop to move values in dx. You have used BP.
Call inst. pushes the IP so you have subtracted 3 from IP using ([bp+24],3) . I was thinking it should be 26. But initially stack is 0. Next statement as you have said adjusted the SP using BP through indirect addressing.

Zulfi.

zak100

call instruction is used specially to get the vaue of IP.

Zulfi.

dedndave


Start:  call    Push_IP             ;this CALL pushes the IP register

Push_IP:
        push    sp
        push    ss
        push    es
        push    ds
        push    cs
        push    bp
        push    si
        push    di
        push    dx
        push    cx
        push    bx
        push    ax
.
.
.
        mov     bp,sp               ;use BP to access the stack values
        sub word ptr [bp+24],3      ;adjust for 3 byte CALL
        add word ptr [bp+22],2      ;adjust for the CALL

after AX has been pushed, we mov the stack pointer (SP) into BP
the SP register points to the last value pushed onto the stack (AX in this case)
then, we can use the BP register to access the values on the stack
remember, the BP register is referenced with the stack segment (SS register)
the SP register may change as things are pushed and popped, but BP will still point to the saved AX value
so, [BP] is the saved value from AX
[BP+2] is the saved value from BX
[BP+22] is the saved value from the SP register
and [BP+24] is the return address from the CALL, which we use to create the displayed IP value