News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Stacks PUSH and POP

Started by Jbarrera, March 23, 2018, 03:22:13 PM

Previous topic - Next topic

Jbarrera

If someone can please help me understand the following code, I would greatly appreciate it.
We are starting to learn about push and pop in my MASM class, and like many, we are using Kip Irvine's stuff.

The questions are the following:
1. what is TYPE DWORD, is that generic for "data" that is DWORD size?
2. How is the function ArraySum falling out Loop L1? add ESI, TYPE DWORD.....what are we adding?
3. Why are we pushing ESI at the start of the function? is it so that when we RET we are back at the start of the array?




; Testing the ArraySum procedure (TestArraySum.asm)

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:dword

.data
array dword 10000h,20000h,30000h,40000h,50000h
theSum dword ?

.code
main proc
mov   esi,OFFSET array ; ESI points to array
mov   ecx,LENGTHOF array ; ECX = array count
call  ArraySum ; calculate the sum
mov   theSum,eax ; returned in EAX

invoke ExitProcess,0
main endp

;-----------------------------------------------------
ArraySum proc
;
; Calculates the sum of an array of 32-bit integers.
; Receives: ESI = the array offset
; ECX = number of elements in the array
; Returns: EAX = sum of the array elements
;-----------------------------------------------------
push  esi ; save ESI, ECX
push  ecx
mov   eax,0 ; set the sum to zero

L1:
add   eax,[esi] ; add each integer to sum
add   esi,TYPE DWORD ; point to next integer
loop  L1 ; repeat for array size
pop   ecx ; restore ECX, ESI
pop   esi
ret ; sum is in EAX
ArraySum endp

end main




Thank you

jj2007

Quote from: Jbarrera on March 23, 2018, 03:22:13 PM1. what is TYPE DWORD, is that generic for "data" that is DWORD size?
Yes, more or less. In reality, it's just the number 4. And nobody writes TYPE DWORD here. Sometimes, we write add esi, DWORD instead of add esi, 4 to indicate that we are working with a DWORD array.

Quote2. How is the function ArraySum falling out Loop L1? add ESI, TYPE DWORD.....what are we adding?
loop is an instruction; read the help file.

Quote3. Why are we pushing ESI at the start of the function? is it so that when we RET we are back at the start of the array?
The registers esi edi ebx ebp are reserved, i.e. you can use them as you like but Windows wants them back in their original state. More here in the section The "register gets trashed" trap

Jbarrera

Ok, that makes sense.

In the example, he pushes ESI and ECX, calculates then POPS back. How about if I want to do something like this (no specifically this but similar)

go into a PROC and push 2 values to the stack so I can use them for something, then exit the PROC



.data

myArray     byte     "3,6",0

.code
main PROC

lea ESI,myArray
call Example


main ENDP

Example PROC
     PUSH  ESI
     PUSH  ebx

     mov     ebx,0
     mov     bl,[esi]
     PUSH   ebx
     add      esi,2
     mov     bl,[esi]
     PUSH   ebx
  ;Do I need to pop off the 2 PUSHes for ebx when I was PUSHing 3 and 6, before I do POP ESI and POP ebx?
 
     POP ESI
     POP ebx
     ret
Example ENDP



or does it scrap everything once it exits Example PROC?



daydreamer

Quote from: Jbarrera on March 24, 2018, 05:11:55 AM
Ok, that makes sense.

In the example, he pushes ESI and ECX, calculates then POPS back. How about if I want to do something like this (no specifically this but similar)

go into a PROC and push 2 values to the stack so I can use them for something, then exit the PROC



.data

myArray     byte     "3,6",0

.code
main PROC

lea ESI,myArray
call Example


main ENDP

Example PROC
     PUSH  ESI
     PUSH  ebx

     mov     ebx,0
     mov     bl,[esi]
     PUSH   ebx
     add      esi,2
     mov     bl,[esi]
     PUSH   ebx
  ;Do I need to pop off the 2 PUSHes for ebx when I was PUSHing 3 and 6, before I do POP ESI and POP ebx?
 
     POP ESI
     POP ebx
     ret
Example ENDP



or does it scrap everything once it exits Example PROC?
You must balance the stack with equal number of POP's as you have PUSH's before RET
Otherwise RET will send execution elsewhere
This is because CALL pushes adress of right where you call your proc, RET retrieves that adress from stack so it can return execution to right after where proc been called
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

Jbarrera

I was reading my assembly book to understand stacks and how to effectively use the stack to indirectly computer data, but I am still confused. I understand c++ better and I know some people have tried explaining using c++ as an example on other forums.

Quote

A stack frame (or activation record) is the area of the stack set aside for passed arguments, subroutine return address, local variables, and saved registers. The stack frame is created by the following sequential steps:
1. Passed arguments, if any, are pushed on the stack.
2. The subroutine is called, causing the subroutine return address to be pushed on the stack.
3. As the subroutine begins to execute, EBP is pushed on the stack.
4. EBP is set equal to ESP. From this point on, EBP acts as a base reference for all of the sub-
routine parameters.
5. If there are local variables, ESP is decremented to reserve space for the variables on the stack.
6. If any registers need to be saved, they are pushed on the stack.


Ok, so the stack frame, is this what would be manipulated when we do push and pops. Does the stack frame already "exist" as a "reserved" space or is it specifically created when doing the following 6 processes?

1. This is, for example, push or pop before calling a procedure. Saving values and addresses so we can get them back when done calling a procedure.
2. Is the subroutine automatic or is this something we are also doing? is this like doing the return after a procedure?
3. EBP is pushed to the stack....is this automatic or do we have to do it?
4. EBP is set to ESP. what information is being handed off here? is it an address or a list of "values / data / addresses".  Also, why do we need to use      EBP is it because EBP will not change automatically?
5. I don't understand exactly what they are referring to." local variables where, on the stack?" Does this apply to addresses too or specifically local variable and by local variables are they referring to stuff inside function or procedures?
6. how is this different from instruction number 1?

jj2007

Go to Google images and search for stack frame push pop eax

Or, even better, get Olly, open a simple exe file and press F7 until you have understood what happens.

Jbarrera

I'm using visual studio, where do i save olly? Or can i just save it to my desktop and open a .asm file with it?

jj2007

Yes. And next time, before posting such a question, try it out. It won't bite you.

RuiLoureiro

Quote from: Jbarrera on March 24, 2018, 05:11:55 AM
Ok, that makes sense.

In the example, he pushes ESI and ECX, calculates then POPS back. How about if I want to do something like this (no specifically this but similar)

go into a PROC and push 2 values to the stack so I can use them for something, then exit the PROC
Quote
.data

myArray     byte     "3,6",0

.code
main PROC

lea ESI,myArray
call Example

main ENDP

Example PROC      ; we dont need to preserve EBP
     PUSH  ESI     ; preserve esi
     PUSH  ebx     ; preserve ebx

     mov     ebx,0   
     mov     bl,[esi]
     ;PUSH   ebx            ; why this ?  -> it is for nothing here
     add      esi,2
     mov     bl,[esi]
    ; PUSH   ebx           ; why another ?

  ;Do I need to pop off the 2 PUSHes for ebx when I was PUSHing 3 and 6, before I do POP ESI and POP ebx?
 
     ;POP ESI
     ;POP ebx

     POP  ebx     ; pop the last push -> ebx
     POP  ESI     ; pop the first push -> esi
     ret     
Example ENDP


or does it scrap everything once it exits Example PROC?