News:

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

Main Menu

QWORD conversion function in MASM32 libraries?

Started by NoCforMe, July 12, 2022, 09:16:26 AM

Previous topic - Next topic

hutch--

 :biggrin:

> know just what the hell [esp-8] refers to?

Just what it says, the memory address in esp with a minus offset of 8 bytes.

This is the normal Intel "complex addressing mode".

When you have a reason to work in QWORD size data in 32 bit, you do it the old fashioned hard way, the low DWORD is read like normal, the high DWORD is read separately and added to the first with a multiplier. The other option is to write it in 64 bit.  :biggrin:

NoCforMe

You're missing the point.

Yes, I know what [esp-n] means. But I don't know what it means when I'm looking at code, meaning that I have no idea what variable it refers to. So why use it instead of a recognizable name? That's why we use a macro assembler, isn't it? Otherwise we'd still be flipping front-panel switches and coding in binary (or even worse, octal). Why use [esp-8] when you can use "pintsDrank" or whatever?

Someone pointed out to me that that notation is useful when using a debugger like Olly which displays stuff that way, but even there it would be a lot nicer to use a meaningful symbolic name rather than some offset from a register, which tells me nothing about what that data is, unless you're some kind of idiot savant who can memorize all that crap.
Assembly language programming should be fun. That's why I do it.

hutch--

Writing no stack frame code comes with practice, you should know what you are passing to a procedure and using direct stack addressing is part of that type of code. The solution of course is to actually comment your code and you will always know what it is. Thank God 64 bit is clearer but under the hood is a joy to behold. It has to be aligned correctly ALA M$ ABI and its written in reverse order below the current stack location.

Now if you want to write no stack frame code with the lowest overhead, if you need temporary locations for what would be LOCAL values in a stackframe procedure, you write it below the stack and this is in 32 bit.

Vortex

Hi NoCforMe,

Hutch's latest post is a nice explanation. If you wish to code an optimized procedure, you need to turn off stack framing and use the complex addressing mode.

Vortex

Hi NoCforMe,

Here is a quick example for you :

include     \masm32\include\masm32rt.inc

subs        PROTO :DWORD,:DWORD

.data

msg         db '120 - 40 = %u',0

.data?

buffer      db 32 dup(?)

.code

start:

    invoke  subs,120,40
   
    invoke  wsprintf,ADDR buffer,\
            ADDR msg,eax

    invoke  StdOut,ADDR buffer

    invoke  ExitProcess,0


OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

align 4

subs PROC x:DWORD,y:DWORD

    mov     eax,DWORD PTR [esp+4]
    sub     eax,DWORD PTR [esp+8]

    ret     2*4 ; balance the stack manually

subs ENDP


OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


END start

NoCforMe

OK, so compare to the way I would do it:

;*****  Subroutine using easy-to-understand arguments instead of [esp+4], etc.:  *****

Subtract PROC minuend:DWORD, subtrahend:DWORD

MOV EAX, minuend
SUB EAX, subtrahend
RET

Subtract ENDP


I fail to see the advantage of your way. What have you gained? Sure, the tiny overhead of the prologue/epilogue code. Is that all? Seems like a small price to pay for readability. Or is there something else I'm missing here?

See, this way I, the human, don't have to keep track of [esp+n] offsets; that's what computers are for ...
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on July 15, 2022, 07:36:16 AMWhat have you gained? Sure, the tiny overhead of the prologue/epilogue code.

That's correct. It's tiny, but if the proc itself is tiny, omitting the overhead may be an advantage.

Here is a more readable alternative: equates.

include \masm32\include\masm32rt.inc

.code
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

subxy proc x0, y0
  x equ [esp+4] ; define your argument
  y equ [esp+8] ; names with equates
  mov eax, x
  sub eax, y
  retn 8
subxy endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

start:
  invoke subxy, 456, 123
  MsgBox 0, cat$(str$(eax), " is the result"), "Hello:", MB_OK
  exit

end start


Same code but different syntax:

include \masm32\include\masm32rt.inc

.code
subxy:
  x equ [esp+4] ; define your argument
  y equ [esp+8] ; names with equates
  mov eax, x
  sub eax, y
  retn 8

start:
  push 123
  push 456
  call subxy
  MsgBox 0, cat$(str$(eax), " is the result"), "Hello:", MB_OK
  exit

end start