Hi everyone :biggrin:
Is anyone able to translate these FASM macros to MASM sintacs :idea:
I would like to free RBP register because if we use static RSP we don,t need RBP
have look what FASM people have:
these are the macros
;First example is the static-RSP procedure frame for 64-bit case.
;These macros define the common frame for all the procedure calls
;inside the "proc" (the same as "frame" macro) and therefore assume
;that RSP is not changed during the procedure life. This allows to
;access the parameters and locals with RSP-based addresses.
;The instructions are longer that with RBP-based addressing,
;however you get the simpler code and RBP register free for
;any custom usage. Choose whatever is more suitable for your needs.
macro static_rsp_prologue procname,flag,parmbytes,localbytes,reglist
{ local counter,loc,regs,frame,current
loc = (localbytes+7) and (not 7)
counter = 0
irps reg, reglist \{ counter = counter+1 \}
regs = 8*( counter + (counter+loc shr 3+1) and 1 )
totalbytes@proc equ frame+loc+regs
sub rsp,totalbytes@proc
localbase@proc equ rsp+frame
regsbase@proc equ rsp+frame+loc
parmbase@proc equ rsp+frame+loc+regs+8
current = 0
current@frame equ current
size@frame equ frame
counter = 0
irps reg, reglist \{ mov [regsbase@proc+8*counter],reg
counter = counter+1 \} }
macro static_rsp_epilogue procname,flag,parmbytes,localbytes,reglist
{ local counter
counter = 0
irps reg, reglist \{ mov reg,[regsbase@proc+8*counter]
counter = counter+1 \}
add rsp,totalbytes@proc
retn }
macro static_rsp_close procname,flag,parmbytes,localbytes,reglist
{ size@frame = current@frame
restore size@frame,current@frame }
prologue@proc equ static_rsp_prologue
epilogue@proc equ static_rsp_epilogue
close@proc equ static_rsp_close
and here is the example what they produce:
proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam
locals
rc RECT
pfd PIXELFORMATDESCRIPTOR
endl
mov [hwnd],rcx
cmp edx,WM_CREATE
je .wmcreate
cmp edx,WM_SIZE
je .wmsize
cmp edx,WM_PAINT
je .wmpaint
cmp edx,WM_KEYDOWN
je .wmkeydown
cmp edx,WM_DESTROY
je .wmdestroy
.defwndproc:
invoke DefWindowProc,rcx,rdx,r8,r9
jmp .finish
.wmcreate:
invoke GetDC,rcx
mov [hdc],rax
lea rdi,[pfd]
mov rcx,sizeof.PIXELFORMATDESCRIPTOR shr 3
xor eax,eax
rep stosq
mov [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
mov [pfd.nVersion],1
mov [pfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW
mov [pfd.iLayerType],PFD_MAIN_PLANE
mov [pfd.iPixelType],PFD_TYPE_RGBA
mov [pfd.cColorBits],16
mov [pfd.cDepthBits],16
mov [pfd.cAccumBits],0
mov [pfd.cStencilBits],0
invoke ChoosePixelFormat,[hdc],addr pfd
invoke SetPixelFormat,[hdc],eax,addr pfd
invoke wglCreateContext,[hdc]
mov [hrc],rax
invoke wglMakeCurrent,[hdc],[hrc]
invoke GetClientRect,[hwnd],addr rc
invoke glViewport,0,0,[rc.right],[rc.bottom]
invoke GetTickCount
mov [clock],eax
xor eax,eax
jmp .finish
.wmsize:
invoke GetClientRect,[hwnd],addr rc
invoke glViewport,0,0,[rc.right],[rc.bottom]
xor eax,eax
jmp .finish
.wmpaint:
invoke GetTickCount
sub eax,[clock]
cmp eax,10
jb .animation_ok
add [clock],eax
invoke glRotatef,float [theta],float dword 0.0,float dword 0.0,float dword 1.0
.animation_ok:
invoke glClear,GL_COLOR_BUFFER_BIT
invoke glBegin,GL_QUADS
invoke glColor3f,float dword 1.0,float dword 0.1,float dword 0.1
invoke glVertex3d,float -0.6,float -0.6,float 0.0
invoke glColor3f,float dword 0.1,float dword 0.1,float dword 0.1
invoke glVertex3d,float 0.6,float -0.6,float 0.0
invoke glColor3f,float dword 0.1,float dword 0.1,float dword 1.0
invoke glVertex3d,float 0.6,float 0.6,float 0.0
invoke glColor3f,float dword 1.0,float dword 0.1,float dword 1.0
invoke glVertex3d,float -0.6,float 0.6,float 0.0
invoke glEnd
invoke SwapBuffers,[hdc]
xor eax,eax
jmp .finish
.wmkeydown:
cmp r8d,VK_ESCAPE
jne .defwndproc
.wmdestroy:
invoke wglMakeCurrent,0,0
invoke wglDeleteContext,[hrc]
invoke ReleaseDC,[hwnd],[hdc]
invoke PostQuitMessage,0
xor eax,eax
.finish:
ret
endp
compiled code:
00000362:a4883EC78 sub (q) rsp,+78
00000366:a48895C2458 mov [rsp+58],rbx
0000036B:a4889742460 mov [rsp+60],rsi
00000370:a48897C2468 mov [rsp+68],rdi
00000375:a48898C2480000000 mov [rsp+00000080],rcx
0000037D:a83FA01 cmp (d) edx,+01
00000380:a7432 je file:000003B4
00000382:a83FA05 cmp (d) edx,+05
00000385:a0F840D010000 je file:00000498
0000038B:a83FA0F cmp (d) edx,+0F
0000038E:a0F843C010000 je file:000004D0
00000394:a81FA00010000 cmp edx,00000100
0000039A:a0F84E5020000 je file:00000685
000003A0:a83FA02 cmp (d) edx,+02
000003A3:a0F84E6020000 je file:0000068F
000003A9:aFF15D11F0000 call (q) [rip+00001FD1]
000003AF:aE920030000 jmpn file:000006D4
000003B4:aFF15FE1F0000 call (q) [rip+00001FFE]
000003BA:a488905A70E0000 mov [rip+00000EA7],rax
000003C1:a488D7C2430 lea rdi,[rsp+30]
000003C6:a48C7C105000000 mov rcx,00000005
000003CD:a31C0 xor eax,eax
000003CF:aF348AB rep; stosq
000003D2:a66C74424302800 mov [rsp+30],0028
000003D9:a66C74424320100 mov [rsp+32],0001
000003E0:aC744243425000000 mov [rsp+34],00000025
000003E8:aC644244A00 mov [rsp+4A],00
000003ED:aC644243800 mov [rsp+38],00
000003F2:aC644243910 mov [rsp+39],10
000003F7:aC644244710 mov [rsp+47],10
000003FC:aC644244200 mov [rsp+42],00
00000401:aC644244800 mov [rsp+48],00
00000406:a488B0D5B0E0000 mov rcx,[rip+00000E5B]
0000040D:a488D542430 lea rdx,[rsp+30]
00000412:aFF159C200000 call (q) [rip+0000209C]
00000418:a488B0D490E0000 mov rcx,[rip+00000E49]
0000041F:a89C2 mov edx,eax
00000421:a4C8D442430 lea r8,[rsp+30]
00000426:aFF1590200000 call (q) [rip+00002090]
0000042C:a488B0D350E0000 mov rcx,[rip+00000E35]
00000433:aFF155F210000 call (q) [rip+0000215F]
00000439:a488905300E0000 mov [rip+00000E30],rax
00000440:a488B0D210E0000 mov rcx,[rip+00000E21]
00000447:a488B15220E0000 mov rdx,[rip+00000E22]
0000044E:aFF1554210000 call (q) [rip+00002154]
00000454:a488B8C2480000000 mov rcx,[rsp+00000080]
0000045C:a488D542420 lea rdx,[rsp+20]
00000461:aFF15491F0000 call (q) [rip+00001F49]
00000467:a48C7C100000000 mov rcx,00000000
0000046E:a48C7C200000000 mov rdx,00000000
00000475:a448B442428 mov r8d,[rsp+28]
0000047A:a448B4C242C mov r9d,[rsp+2C]
0000047F:aFF150B210000 call (q) [rip+0000210B]
00000485:aFF15331E0000 call (q) [rip+00001E33]
0000048B:a8905130E0000 mov [rip+00000E13],eax
00000491:a31C0 xor eax,eax
00000493:aE93C020000 jmpn file:000006D4
00000498:a488B8C2480000000 mov rcx,[rsp+00000080]
000004A0:a488D542420 lea rdx,[rsp+20]
000004A5:aFF15051F0000 call (q) [rip+00001F05]
000004AB:a48C7C100000000 mov rcx,00000000
000004B2:a48C7C200000000 mov rdx,00000000
000004B9:a448B442428 mov r8d,[rsp+28]
000004BE:a448B4C242C mov r9d,[rsp+2C]
000004C3:aFF15C7200000 call (q) [rip+000020C7]
000004C9:a31C0 xor eax,eax
000004CB:aE904020000 jmpn file:000006D4
000004D0:aFF15E81D0000 call (q) [rip+00001DE8]
000004D6:a2B05C80D0000 sub eax,[rip+00000DC8]
000004DC:a83F80A cmp (d) eax,+0A
000004DF:a722F jc file:00000510
000004E1:a0105BD0D0000 add [rip+00000DBD],eax
000004E7:a660F6E052D0D0000 movd xmm0,[rip+00000D2D]
000004EF:aB800000000 mov eax,00000000
000004F4:a660F6EC8 movd xmm1,eax
000004F8:aB800000000 mov eax,00000000
000004FD:a660F6ED0 movd xmm2,eax
00000501:aB80000803F mov eax,3F800000
00000506:a660F6ED8 movd xmm3,eax
0000050A:aFF1570200000 call (q) [rip+00002070]
00000510:a48C7C100400000 mov rcx,00004000
00000517:aFF154B200000 call (q) [rip+0000204B]
0000051D:a48C7C107000000 mov rcx,00000007
00000524:aFF1536200000 call (q) [rip+00002036]
0000052A:aB80000803F mov eax,3F800000
0000052F:a660F6EC0 movd xmm0,eax
00000533:aB8CDCCCC3D mov eax,3DCCCCCD
00000538:a660F6EC8 movd xmm1,eax
0000053C:aB8CDCCCC3D mov eax,3DCCCCCD
00000541:a660F6ED0 movd xmm2,eax
00000545:aFF1525200000 call (q) [rip+00002025]
0000054B:a48B8333333333333E3BF mov rax,BFE3333333333333
00000555:a66480F6EC0 movd xmm0,rax
0000055A:a48B8333333333333E3BF mov rax,BFE3333333333333
00000564:a66480F6EC8 movd xmm1,rax
00000569:a48C7C000000000 mov rax,00000000
00000570:a66480F6ED0 movd xmm2,rax
00000575:aFF150D200000 call (q) [rip+0000200D]
0000057B:aB8CDCCCC3D mov eax,3DCCCCCD
00000580:a660F6EC0 movd xmm0,eax
00000584:aB8CDCCCC3D mov eax,3DCCCCCD
00000589:a660F6EC8 movd xmm1,eax
0000058D:aB8CDCCCC3D mov eax,3DCCCCCD
00000592:a660F6ED0 movd xmm2,eax
00000596:aFF15D41F0000 call (q) [rip+00001FD4]
0000059C:a48B8333333333333E33F mov rax,3FE3333333333333
000005A6:a66480F6EC0 movd xmm0,rax
000005AB:a48B8333333333333E3BF mov rax,BFE3333333333333
000005B5:a66480F6EC8 movd xmm1,rax
000005BA:a48C7C000000000 mov rax,00000000
000005C1:a66480F6ED0 movd xmm2,rax
000005C6:aFF15BC1F0000 call (q) [rip+00001FBC]
000005CC:aB8CDCCCC3D mov eax,3DCCCCCD
000005D1:a660F6EC0 movd xmm0,eax
000005D5:aB8CDCCCC3D mov eax,3DCCCCCD
000005DA:a660F6EC8 movd xmm1,eax
000005DE:aB80000803F mov eax,3F800000
000005E3:a660F6ED0 movd xmm2,eax
000005E7:aFF15831F0000 call (q) [rip+00001F83]
000005ED:a48B8333333333333E33F mov rax,3FE3333333333333
000005F7:a66480F6EC0 movd xmm0,rax
000005FC:a48B8333333333333E33F mov rax,3FE3333333333333
00000606:a66480F6EC8 movd xmm1,rax
0000060B:a48C7C000000000 mov rax,00000000
00000612:a66480F6ED0 movd xmm2,rax
00000617:aFF156B1F0000 call (q) [rip+00001F6B]
0000061D:aB80000803F mov eax,3F800000
00000622:a660F6EC0 movd xmm0,eax
00000626:aB8CDCCCC3D mov eax,3DCCCCCD
0000062B:a660F6EC8 movd xmm1,eax
0000062F:aB80000803F mov eax,3F800000
00000634:a660F6ED0 movd xmm2,eax
00000638:aFF15321F0000 call (q) [rip+00001F32]
0000063E:a48B8333333333333E3BF mov rax,BFE3333333333333
00000648:a66480F6EC0 movd xmm0,rax
0000064D:a48B8333333333333E33F mov rax,3FE3333333333333
00000657:a66480F6EC8 movd xmm1,rax
0000065C:a48C7C000000000 mov rax,00000000
00000663:a66480F6ED0 movd xmm2,rax
00000668:aFF151A1F0000 call (q) [rip+00001F1A]
0000066E:aFF15041F0000 call (q) [rip+00001F04]
00000674:a488B0DED0B0000 mov rcx,[rip+00000BED]
0000067B:aFF15431E0000 call (q) [rip+00001E43]
00000681:a31C0 xor eax,eax
00000683:aEB4F jmps file:000006D4
00000685:a4183F81B cmp (d) r8d,+1B
00000689:a0F851AFDFFFF jne file:000003A9
0000068F:a48C7C100000000 mov rcx,00000000
00000696:a48C7C200000000 mov rdx,00000000
0000069D:aFF15051F0000 call (q) [rip+00001F05]
000006A3:a488B0DC60B0000 mov rcx,[rip+00000BC6]
000006AA:aFF15F01E0000 call (q) [rip+00001EF0]
000006B0:a488B8C2480000000 mov rcx,[rsp+00000080]
000006B8:a488B15A90B0000 mov rdx,[rip+00000BA9]
000006BF:aFF15FB1C0000 call (q) [rip+00001CFB]
000006C5:a48C7C100000000 mov rcx,00000000
000006CC:aFF15F61C0000 call (q) [rip+00001CF6]
000006D2:a31C0 xor eax,eax
000006D4:a488B5C2458 mov rbx,[rsp+58]
000006D9:a488B742460 mov rsi,[rsp+60]
000006DE:a488B7C2468 mov rdi,[rsp+68]
000006E3:a4883C478 add (q) rsp,+78
000006E7:aC3 retn
Hi habran,
so far I can see, is the assembled binary code MASM compatible. They use RSP or RIP relative addressing and therefore is RBP free for use for other purposes. That's an old technique which one can use in 32 bit Windows, too.
For the FASM macros, you should start an appropriate thread in that forum. I haven't used FASM so far, but there are FASM fans all around the world. Andreas (Japheth) has experiences with FASM; may be that he could help a bit.
Gunther
Quote from: Gunther on April 25, 2013, 06:43:21 AMThey use RSP or RIP relative addressing and therefore is RBP free for use for other purposes. That's an old technique which one can use in 32 bit Windows, too.
How would you do that?
call dword ptr [eip+20h] throws an error...
Dear Habran,
Here is the FASM site.
http://board.flatassembler.net/index.php
Andy
Jochen,
Quote from: jj2007 on April 25, 2013, 07:19:41 AM
How would you do that? call dword ptr [eip+20h] throws an error...
Please, don't misunderstand me. The old technique is to use
ESP for addressing the stack parameters. For the
RIP relative addressing isn't a counterpart in the 32 bit world. That's new, because the register
RIP is new, too. :icon_cool:
Gunther
Thanks for clarifying that, Gunther. Of course, jmp is an instruction that uses eip-relative addressing, but I had hoped for a moment that you knew some old secrets ;)
call $+20h
or did you mean...
call dword ptr [rsp+20h]
Gunther, thanks for understanding what is it about
it can be done as well to EBP in 32 bit :icon14:
Dear Magnum, I know very well where is FASM site and I am not
favoring FASM, I love JWASM and do not intend to change it :bgrin:
However, I wanted to translate these macros so that we can use them with JWASM or MASM
Hey JJ, you are The Lord Of The Macros, what do you say about it :biggrin:
Quote from: habran on April 25, 2013, 02:12:02 PMHowever, I wanted to translate these macros so that we can use them with JWASM or MASM
Hey JJ, you are The Lord Of The Macros, what do you say about it :biggrin:
Hey, qWord will beat you up if he reads that :eusa_naughty:
Besides, it's national holiday here, and I am not supposed to work 8)
But, since I am a nice guy, see attached an excerpt of a famous Masm library (.asc, to be opened in RichMasm or WordPad or Ms Word). It does what you want, it seems ;)
thanks JJ, it looks promissing :t
QuoteHey, qWord will beat you up if he reads that :eusa_naughty:
I am not a chicken, I have some marshal art skills 8)
Anyway, he is never there when I need him :P
QuoteBesides, it's national holiday here, and I am not supposed to work 8)
how can you think about programming as a work :icon_eek:
to me it is like breathing a fresh air
No programming-No life ;)
QuoteI am not a chicken, I have some marshal art skills
http://www.youtube.com/watch?v=1-fV2EfSa8c (http://www.youtube.com/watch?v=1-fV2EfSa8c)
"you're supposed to be my backup !"
"i was your backup, didn't your ass get back up ?" :lol:
Quote from: habran on April 25, 2013, 06:31:40 AM
Is anyone able to translate these FASM macros to MASM sintacs :idea:
I guess it's not too hard to to a literal translation.
However, I'm afraid it's as useful and comprehensible as if I translate the German metaphor "den Kopf in den Sand stecken" into "to put one's head into the sand".
IOW: it probably won't get you far, because FASM is different: be aware that the procedure stuff ( proc, locals, invoke ) is implemented as macros in FASM, while in Masm/JWasm it's an integral part of the assembler.
dedndave, you are amazing, thanks for that :P
japheth, I know that it would be a chickenshit for you to implement it in JWasm
however, you said you will take a break from JWasm development and I appreciate it :t
so I am trying to find another solution for my goal because I want it badly :greenclp:
I know that anything is possible if you really want it
I am trying to solve it with macros if possible
if not, I will have to dig in your source code to find a solution
If M$ can do it with C we can do it with JWasm better
I promise you I want give up on this 8)
jj2007, the macro your posted is not what I was looking for but it has some elements that can be used
I will try to make of it what I need
this is what I want to accomplish:
somefunction PROC FRAME USES r12 r13 r14 r15 somevar:QWORD
mov [rsp+8], rbp ;these 4 registers could be stored
mov [rsp+16], rbx ;in a shadow space
mov [rsp+24], rdi ;if we need to use rcx, rdx, r8, r9
mov [rsp+32], rsi ;we can put them in rbp, rbx, rdi, rsi
push r12
push r13
push r14
push r15
sub rsp, 1040 ;locals + @ReservedStack
;some code here
;..............
;
add rsp, 1040
pop r15
pop r14
pop r13
pop r12
mov rbp, [rsp+8]
mov rbx, [rsp+16]
mov rdi, [rsp+24]
mov rsi, [rsp+32]
ret
somefunction ENDP
Now I need to set LOCALS so that compiler can calculate locations on the stack
the macro you posted calls "SetGlobals"
however it could be changed to do the job
it should probably create something like:
var1 EQU 128+24
var2 EQU 128+16
var3 EQU 128+8
Hi Dave,
Quote from: dedndave on April 25, 2013, 04:44:06 PM
http://www.youtube.com/watch?v=1-fV2EfSa8c (http://www.youtube.com/watch?v=1-fV2EfSa8c)
funny video, indeed. :t
Gunther
Attached a sample code using sLocal (like stack-local). Usage:
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
MyTest proc par1, par2
push esi ; save esi
sLocal First:DWORD, rc:RECT, wc:WNDCLASSEX
sLocal Last[1]:BYTE
sLocal
sub edi, esp
print str$(sPara(1)), 9, "par1", 13, 10
print str$(sPara(2)), 9, "par2", 13, 10
lea eax, First
sub eax, esp
print str$(eax), 9, "First", 13, 10
lea ecx, Last
sub ecx, esp
print str$(ecx), 9, "Last", 13, 10, 10
sLocal end
pop esi ; restore the stack
retn 1*4
MyTest endp
32-bit code, no MasmBasic. One caveat is that you cannot use the same sLocal name in a second proc, since Masm does not allow redefinition of integers in text format. There is a possible workaround using PURGE and macros, but it would be an overkill.
good job jj2007 :t
you are getting closer to my goal, thanks for your effort :biggrin:
if we could get read of 's' in sLOCALS it would be great
for naming vars we can find easy solution
my intention is to keep source looking as usual so that we don't have to rewrite sources
Getting rid of the "s" is easy:
OPTION NOKEYWORD:<LOCAL>
LOCAL equ <sLocal>
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
MyTest proc par1, par2
push esi ; save esi
LOCAL First:DWORD, rc:RECT, wc:WNDCLASSEX
LOCAL Last[1]:BYTE
LOCAL
sub edi, esp
print str$(sPara(1)), 9, "P1", 13, 10
print str$(sPara(2)), 9, "P2", 13, 10
lea eax, First
sub eax, esp
print str$(eax), 9, "First", 13, 10
lea ecx, Last
sub ecx, esp
print str$(ecx), 9, "Last", 13, 10, 10
LOCAL end
pop esi ; restore the stack
retn 1*4
MyTest endp
But the question is "what for?"...
I was always told 64-bit is so much faster because you never run short of registers :P
Jochen,
Quote from: jj2007 on April 26, 2013, 03:41:36 PM
But the question is "what for?"...
I was always told 64-bit is so much faster because you never run short of registers :P
you're quiet right. I don't understand, because parameters are passed via registers (according to the Windows 64 bit ABI (http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx)).
Gunther
you may want to time these code methods
in the end, it may be better to use RBP/EBP the normal way and use a couple locals to store extra values
i think the processors have been optimized to access stack data using the base pointer register
i sometimes use "fake" register names to write a loop
then, when i am done, the lesser-often accessed items get moved to locals
and the more-often accessed items get registers :P
push and pop aren't bad, either
i remember writing a loop, where i needed EBP for some rather intensive and long math code
i needed one extra variable at the end of the loop - the count, accessed once each pass
i used a global dword - seemed to work pretty well
Quote from: dedndave on April 26, 2013, 09:07:43 PM
you may want to time these code methods
No time for that ;)
Anyway, useful or not, it was a nice exercise in macro writing. Here is the luxury version, with "uses" and push & pop and stack balance control:
MyTest proc par1, par2 ; two paras passed
LOCAL First:DWORD, rc:RECT, wc:WNDCLASSEX
LOCAL Last[1]:BYTE
LOCAL uses esi edi ; we preserve two regs
mov rc.left, 12300
xPush eax ; don't use normal push...!
xPush 999
add rc.left, 45 ; result should be 12345
print hex$(sPara(1)), 9, "par1", 13, 10 ; show the two paras passed ...
print hex$(sPara(2)), 9, "par2", 13, 10 ; ... correctly, despite the two xPushes
xPop ecx
mov ecx, rc.left
print str$(ecx), 9, "rc.left - works because 'mov ecx, rc.left' yields correct result", 13, 10
print str$(rc.left), 9, "rc.left - fails because 'print' pushes paras!!", 13, 10, 10
xPop edx
LOCAL end ; macro will shout at you if your stack is not balanced
retn 2*DWORD
MyTest endp
Well done JJ2077 :t
that one is the deluxe macro
now you have left with one mo job: overkill or underkill try to make locals reusable, please ;)
Hey guys, I want to explain to you why is it that I want to free RBP
when you work with a lot of structures it is much easier and faster to use nonvolatile register
as well as in loops
instead of writing for example:
LOCAL Mystruct :GOODSTRUCT
mov rax, Mystruct
mov rax,[rax].GOODSTRUCT.txt
mov rax,[rax].TEXTSTRUCT.data
.if !rax
jmp aexit
.endif
mov rax, Mystruct
mov rax,[rax].GOODSTRUCT.opt
mov rax,[rax].OPTSTRUCT.data
.if !rax
jmp aexit
.endif
I can write like this:
LOCAL Mystruct :GOODSTRUCT
mov rbp, Mystruct
mov r15,[rbp].GOODSTRUCT.txt
mov r12,[rbp].GOODSTRUCT.opt
mov rcx,[r15].TEXTSTRUCT.data
mov rax,[r12].OPTSTRUCT.data
now I don't need to reshuffle again and again my pointers but they are ready to access immediately
so, now if I am working with several structures, any additional nonvolatile register is welcome
and when working with .while or .for ebx or ebp can be used as counters because they don't get changed
when you call some function