News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

General purpose registers values program

Started by felipe, May 25, 2022, 10:58:51 AM

Previous topic - Next topic

felipe

I'm happy to report that i have coded again, although a very simple program, but it was fun as always has been. This little console program will show in the console window the values of the general purpose registers before the execution of the first instruction of the program. You exit the program by pressing ENTER (intro, return, etc), or you can just close the console window.

I attach the source, the .exe and a bat file with the simple commands to assemble and run. But for this .bat file to work, you will have to run it in the same path as ml64. You can do all the changes you need/want to all this stuff (including, of course, the code).

It will be good if at least someone gives feedback about other ideas to show the values of the registers, since after thinking for a while, i only got the idea of processing each nibble (nibble by nibble). Don't know if that's the standard way to do it or the slowest one... :toothy:

Btw, i have changed my style of indentation by using no indentation whatsoever, hopefully that doesn't turn anyone crazy... :mrgreen:

hutch--

Hi felipe,

Code works fine but the left aligned code I find really hard to read.

felipe

Sorry Hutch i will change that at other time. By now i have fixed a little bug (i was showing the pushed registers 1 qword displaced). I fixed the error in this attachment.


felipe

Now works all fine.
here is what the program shows in my computer:
This are the values of the general purpose registers
before the execution of the first instruction of this program.
Press RETURN to exit the program...

RAX: 0000000000000000
RBX: 00007FF6B8F01000
RCX: 00007FF6B8DEF000
RDX: 00007FF6B8F01000
RSI: 00007FF6B8DEF000
RDI: 00007FF6B8DEF000
RBP: 0000000000000000
RSP: 000000978765FC28
R8: 00007FF6B8DEF000
R9: 0000000000000000
R10: 0000000000000000
R11: 0000000000000000
R12: 0000000000000000
R13: 0000000000000000
R14: 0000000000000000
R15: 0000000000000000


And below (hopefully you can see it) there's an image of what the debugger shows in the registers at the entry point of the program.

jj2007

Quote from: felipe on May 25, 2022, 12:32:30 PM
Sorry Hutch i will change that at other time. By now i have fixed a little bug (i was showing the pushed registers 1 qword displaced). I fixed the error in this attachment.

C:\Masm32\Members\Felipe>ml64 /c registers.asm
"ml64" non è riconosciuto come comando interno o esterno,
un programma eseguibile o un file batch.

C:\Masm32\Members\Felipe>link /subsystem:console /entry:start registers.obj
"link" non è riconosciuto come comando interno o esterno,
un programma eseguibile o un file batch.


Apparently you rely on environment variables :sad:

This works better:

\Masm64\bin\ml64 /c registers.asm
\Masm64\bin\link /subsystem:console /entry:start registers.obj
registers.exe


RAX: 0000000077065560
RBX: 0000000000000000
RCX: 000007FFFFFDF000
RDX: 000000013FC61000
RSI: 0000000000000000
RDI: 0000000000000000
RBP: 0000000000000000
RSP: 000000000025F948
R8: 000007FFFFFDF000
R9: 000000013FC61000
R10: 0000000000000000
R11: 0000000000000000
R12: 0000000000000000
R13: 0000000000000000
R14: 0000000000000000
R15: 0000000000000000


For comparison, using deb:

x:rax   1234567890abcdefh
x:rbx   1400022b0h
x:rcx   0h
x:rdx   0h
x:rsi   0h
x:rdi   0h
x:rbp   12ff50h
x:rsp   12fed0h
x:r8    12fd48h
x:r9    12ff50h
x:r10   335040h
x:r11   12fb22h
x:r12   0h
x:r13   0h
x:r14   0h
x:r15   0h

This program was assembled with ml64 in 64-bit format.


The reason for differences is that there are some initialisation routines before deb starts working.

My debugger shows this on entry point (compare to your rsp, rsi, rdi!):

hutch--

There are different ways of doing this in 64 bit. I use a technique for the accessory "livedb.exe".

felipe

@jj2007 aside the problem with the .bat file, i don't get clear what are you pointing. Would you be more explicit please?

felipe

Here's the code with a more classic indentation (also attached):

; Program that shows general purpose registers values.

option casemap:none
include /masm32/include64/win64.inc
include /masm32/include64/kernel32.inc
includelib /masm32/lib64/kernel32.lib

.data
rax_reg byte "RAX: ", 16 dup(0h),0dh,0ah
rbx_reg byte "RBX: ", 16 dup(0h),0dh,0ah
rcx_reg byte "RCX: ", 16 dup(0h),0dh,0ah
rdx_reg byte "RDX: ", 16 dup(0h),0dh,0ah
rsi_reg byte "RSI: ", 16 dup(0h),0dh,0ah
rdi_reg byte "RDI: ", 16 dup(0h),0dh,0ah
rbp_reg byte "RBP: ", 16 dup(0h),0dh,0ah
rsp_reg byte "RSP: ", 16 dup(0h),0dh,0ah
r8_reg byte "R8: ", 16 dup(0h),0dh,0ah
r9_reg byte "R9: ", 16 dup(0h),0dh,0ah
r10_reg byte "R10: ", 16 dup(0h),0dh,0ah
r11_reg byte "R11: ", 16 dup(0h),0dh,0ah
r12_reg byte "R12: ", 16 dup(0h),0dh,0ah
r13_reg byte "R13: ", 16 dup(0h),0dh,0ah
r14_reg byte "R14: ", 16 dup(0h),0dh,0ah
r15_reg byte "R15: ", 16 dup(0h)
con_title byte "GENERAL PURPOSE REGISTERS VALUES",0h
info_text byte "This are the values of the general purpose registers",0ah,0dh, "before the execution of the first instruction of this program.",0ah,0dh, \
                "Press RETURN to exit the program...",0dh,0ah,0dh,0ah

input_buff qword 0h
chars_written qword 0h
chars_readed qword 0h

.code
start proc
      push rsp
      push rcx
      push rdx
      push r8
      push r9
      sub rsp,30h
      mov rcx,rax
      lea rdx,rax_reg
      mov r8,sizeof rax_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rax.
      mov rcx,rbx
      lea rdx,rbx_reg
      mov r8,sizeof rbx_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rbx.
      mov rcx,rsi
      lea rdx,rsi_reg
      mov r8,sizeof rsi_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rsi.
      mov rcx,rdi
      lea rdx,rdi_reg
      mov r8,sizeof rdi_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rdi.
      mov rcx,r15
      lea rdx,r15_reg
      mov r8,sizeof r15_reg
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r15.
      mov rcx,r14
      lea rdx,r14_reg
      mov r8,sizeof r14_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r14.
      mov rcx,r13
      lea rdx,r13_reg
      mov r8,sizeof r13_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r13.
      mov rcx,r12
      lea rdx,r12_reg
      mov r8,sizeof r12_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r12.
      mov rcx,r11
      lea rdx,r11_reg
      mov r8,sizeof r11_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r11.
      mov rcx,r10
      lea rdx,r10_reg
      mov r8,sizeof r10_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r10.
      mov rcx,rbp
      lea rdx,rbp_reg
      mov r8,sizeof rbp_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rbp.
      mov rcx,[rsp+30h]
      lea rdx,r9_reg
      mov r8,sizeof r9_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r9.
      mov rcx,[rsp+38h]
      lea rdx,r8_reg
      mov r8,sizeof r8_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of r8.
      mov rcx,[rsp+40h]
      lea rdx,rdx_reg
      mov r8,sizeof rdx_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rdx.
      mov rcx,[rsp+48h]
      lea rdx,rcx_reg
      mov r8,sizeof rcx_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rcx.
      mov rcx,[rsp+50h]
      lea rdx,rsp_reg
      mov r8,sizeof rsp_reg
      sub r8,2 ; Discard 0dh and 0ah.
      mov r9,16 ; 16 nibbles.
      call reg_value ; Get value of rsp.
      call FreeConsole ; Detach process of inherited console
      call AllocConsole ;  and create a new one.
      lea rcx,con_title
      call SetConsoleTitle
      mov rcx,STD_OUTPUT_HANDLE
      call GetStdHandle
      mov r15,rax ; Output handle.
      mov rcx,r15
      lea rdx,info_text
      mov r8,sizeof info_text
      lea r9,chars_written
      mov qword ptr[rsp+20h],NULL
      call WriteConsole
      mov rcx,r15 ; Output handle.
      lea rdx,rax_reg
      mov r8,sizeof rax_reg
      add r8,sizeof rbx_reg
      add r8,sizeof rsi_reg
      add r8,sizeof rdi_reg
      add r8,sizeof rcx_reg
      add r8,sizeof rdx_reg
      add r8,sizeof rsp_reg
      add r8,sizeof rbp_reg
      add r8,sizeof r8_reg
      add r8,sizeof r9_reg
      add r8,sizeof r10_reg
      add r8,sizeof r11_reg
      add r8,sizeof r12_reg
      add r8,sizeof r13_reg
      add r8,sizeof r14_reg
      add r8,sizeof r15_reg
      lea r9,chars_written
      mov qword ptr[rsp+20h],NULL
      call WriteConsole
      mov rcx,STD_INPUT_HANDLE
      call GetStdHandle
      mov r15,rax ; Input handle.
      mov rcx,r15
      mov rdx,ENABLE_LINE_INPUT
      call SetConsoleMode
      mov rcx,r15
      lea rdx,input_buff
      mov r8,1 ; Read just the character CR.
      lea r9,chars_readed
      mov qword ptr[rsp+20h],NULL
      call ReadConsole
      xor rcx,rcx
      call ExitProcess
start endp

reg_value proc
          push rbp
          mov rbp,rsp
          next_nibble:
          mov rsp,rcx
          and rcx,0fh ; Isolate lsb.
          cmp rcx,09h
          ja can_be_a
          or rcx,30h ; To ascii.
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          can_be_a:
          cmp rcx,0ah
          jne can_be_b
          mov rcx,'A'
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          can_be_b:
          cmp rcx,0bh
          jne can_be_c
          mov rcx,'B'
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          can_be_c:
          cmp rcx,0ch
          jne can_be_d
          mov rcx,'C'
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          can_be_d:
          cmp rcx,0dh
          jne can_be_e
          mov rcx,'D'
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          can_be_e:
          cmp rcx,0eh
          jne is_f
          mov rcx,'E'
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          is_f:
          mov rcx,'F'
          dec r8
          mov [rdx+r8],cl
          dec r9
          and r9,r9
          jz all_done
          mov rcx,rsp
          shr rcx,4
          jmp next_nibble
          all_done:
          mov rsp,rbp
          pop rbp
          ret
reg_value endp
end

felipe

Here is the output with other debbuger of the registers values in the entry point of the program (in the image below) and here is the same output in the program while it's running under this debugger:

This are the values of the general purpose registers
before the execution of the first instruction of this program.
Press RETURN to exit the program...

RAX: 0000000000000000
RBX: 00007FF640491000
RCX: 00007FF63F9CF000
RDX: 00007FF640491000
RSI: 00007FF63F9CF000
RDI: 00007FF63F9CF000
RBP: 0000000000000000
RSP: 000000DF6839FD88
R8: 00007FF63F9CF000
R9: 0000000000000000
R10: 0000000000000000
R11: 0000000000000000
R12: 0000000000000000
R13: 0000000000000000
R14: 0000000000000000
R15: 0000000000000000


Again are the same, the little bug from yesterday was fixed, the program its working well. But you are welcome to point out the opposite (with arguments).  :bgrin:

jj2007

Quote from: felipe on May 25, 2022, 09:35:46 PM
@jj2007 aside the problem with the .bat file, i don't get clear what are you pointing. Would you be more explicit please?

Nothing in particular, your program works fine :thumbsup:

Just keep in mind that not everybody uses environment variables (they are relict from DOS times). Both the Masm32 and Masm64 SDKs have one fine feature: they reside at the root, at \Masmxx\

So you don't need environment variables. This will work fine:
\Masm64\bin\ml64 /c registers.asm
\Masm64\bin\link /subsystem:console /entry:start registers.obj


However, I see that you are using this:
include /masm32/include64/win64.inc
include /masm32/include64/kernel32.inc
includelib /masm32/lib64/kernel32.lib


Did you get the latest Masm64 SDK? If so, why didn't you install it to its default directory, i.e. \Masm64?

I'm not sure about the use of /forward/slashes, but they are about as common as code with no indentation :cool:

felipe

That's weird, last time i remember, to use the masm64 sdk it has to be installed in a folder named masm32. ¿Did that changed with an updated version? If that's the case, please give me a link to the lastest version. About the slashes you are right, that's a problem that comes with the amount of time from my last program. I will remember it.
Btw, i'm not using environment variables by my own, the console of the build tools (from microsoft) set them, i think with a file named vcvarsall.bat.
Last but not least, thanks to all who tried (hopefully) the last/correct version.  :thup:


felipe

About the link, i think i have found it, thanks.  :thup:

hutch--

Hi felipe,

The earlier version while I was developing the SDK was attached to the MASM32 installation but the later version is MASM64 which is 64 bit only. I will have another version done shortly which is a lot more complete. I am currently working on a 64 bit editor which I have up and running but to replace QE will take a lot more work. QE is set up to work with the 64 bit SDK and apart from getting a few of the menu items working correctly, its very reliable.

felipe


daydreamer

great work felipe :thumbsup:
just wonder if I get different register values depending on it is run directly after linker or use a .bat file that starts it after another program?
or it is the windows .bat file handler registers after?
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding