Re: how to push local variables onto the stack?
Posted: Mon May 08, 2017 12:49 pm
I've done some testing to get a clearer picture.
I've written this PB code (PB 5.60 Win x86) and compiled it via CLI with the /COMMENTED option to create the ASM source file output and peek in it:
If my understdaing of the output ASM source is correct, the vars a, b, and c in the code main body are allocated on the heap. In the final ASM source they are found toward the end, inside the .bss section (abridged code, lines 136–):
The TestProc() in the source is (lines 83-108):
... so it seems that PB's approach is to first fill the stack by PUSHing some 0 valued DWs (as many as the number of local variables about to create) and then fill the stack with the local vars by MOVing their values by using ESP-relative addressing (ie: ESP, ESP+4, ESP+8).
The local variables names are then defined as symbolic constants, using the same ESP-relative principle:
From Fasm documentation:
Wasn't there a way to define the constant so that it's value is immutable, regardless of value changes in ESP after declaration -- ie: that all further references are not influenced by ESP? I feel like I'm missing out something here ...
NOTE 1: p.v_aa, p.v_bb and p.v_cc vars will only be created if there some inline ASM code that handles them. If from the above PB source you remove the inline-ASM line of code, those variables will just be put on the stack, but no constants will be created for referencing them by name.
I've written this PB code (PB 5.60 Win x86) and compiled it via CLI with the /COMMENTED option to create the ASM source file output and peek in it:
Code: Select all
; PB 5.60 x86
Declare TestProc()
a = 10
b = 20
c = 30
TestProc()
Procedure TestProc()
Protected aa = 10
Protected bb = 20
Protected cc = 30
! MOV dword [p.v_cc], 99
EndProcedure
Code: Select all
section '.bss' readable writeable
_PB_BSSSection:
align 4
; [ ... ]
PB_DataPointer rd 1
v_a rd 1
v_b rd 1
v_c rd 1
; [ ... ]
I_BSSEnd:
Code: Select all
; Procedure TestProc()
_Procedure0:
PS0=16
XOR eax,eax
PUSH eax
PUSH eax
PUSH eax
; Protected aa = 10
MOV dword [esp],10
; Protected bb = 20
MOV dword [esp+4],20
; Protected cc = 30
MOV dword [esp+8],30
;
; ! MOV dword [p.v_cc], 99
p.v_aa equ esp+0
p.v_bb equ esp+4
p.v_cc equ esp+8
MOV dword [p.v_cc], 99
; EndProcedure
_EndProcedureZero1:
XOR eax,eax
_EndProcedure1:
ADD esp,12
RET
;
The local variables names are then defined as symbolic constants, using the same ESP-relative principle:
Code: Select all
p.v_aa equ esp+0
p.v_bb equ esp+4
p.v_cc equ esp+8
So, if I've understood correctly, every time p.v_aa is referenced, it's value will be computed based on the value of ESP at the time it's being referenced --- and not at the value of ESP at the time of the constant declaration! Is it so?2.3.2 Symbolic constants
The symbolic constants are different from the numerical constants, before the assembly process they are replaced with their values everywhere in source lines after their definitions, and anything can become their values.
The definition of symbolic constant consists of name of the constant followed by the equ directive. Everything that follows this directive will become the value of constant. If the value of symbolic constant contains other symbolic constants, they are replaced with their values before assigning this value to the new constant.
Wasn't there a way to define the constant so that it's value is immutable, regardless of value changes in ESP after declaration -- ie: that all further references are not influenced by ESP? I feel like I'm missing out something here ...
NOTE 1: p.v_aa, p.v_bb and p.v_cc vars will only be created if there some inline ASM code that handles them. If from the above PB source you remove the inline-ASM line of code, those variables will just be put on the stack, but no constants will be created for referencing them by name.