News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

PROCEDURES

Started by seymour_glass, March 30, 2006, 09:08:25 PM

Previous topic - Next topic

seymour_glass

Im just getting into writing procedures.  Anyone got any good resources for this?  As in parameters....pushing, popping (i understand them, but not like i think i should) , stack and index pointers?

Seymour

Ratch

seymour_glass,
     A lot of folks from the Ineffable All disagree with me, because I never use PROC's.  I think they are just a bunch of red tape that gets in-between the problem and the programmer.  Anyway, look at the references below.  Some will say that this method is too advanced for a beginner, and that is possibly true.  The choice is yours.  Tell me what you think. Ratch

http://www.masmforum.com/simple/index.php?topic=2371.0 see reply #4
http://www.masmforum.com/simple/index.php?topic=380.0  see replys #11,17

hutch--

Seymour,

The techniques Ratch is talking about are probably a bit advanced for someone learning assembler. I would suggest that you start with normal stack frame procedures, once you have them going you can start on writing procedures with no stack frame and if you have some need later on, you can try out various techniques for short circuiting procedure CALL/RET branching.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Mark Jones

Hi Seymour, perhaps these posts will help you. It touches on both procedures and the stack.
http://www.masmforum.com/simple/index.php?topic=4276.msg32166#msg32166

Also, be sure to read \masm32\help\ASMINTRO.HLP. :U
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

seymour_glass

ok question....To  exchange two registers, one could.... 

push eax
push ebx
pop  eax
pop  ebx

Correct?

why then would:

push eax
mov eax, ebx
pop ebx

work?
Can you even pop something off that youu didnt push on?  I guess thats why this confuses me....plus my textbook sux....

_______

Also, can anyone briefly explain the PUBLIC and EXTRN directives? 

(sorry for these petty questions, ive got no other consolation for my problems.)

Seymour

hutch--

seymour,

You have to realise that the stack is memory so when you push a register onto the stack, the value in the register is then stored in memory. The stack is a last on, first off layout and as long as you don't change the stack pointer (ESP) it will return the last item you pushed onto it.

The method you have shown to exchange register is perfectly valid as it uses the first on, last off technique to swap the register contents.


push eax
mov eax, ebx
pop ebx


When you use "push eax", the value in EAX is copied to the stack memory.

Moving EBX into EAX does not effect this and when you do the "pop EBX" you are copying the value on the stack into EBX.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

seymour_glass

I see that now.  I just thought that it was a little more structured. Logically you cant take something off if you dont put it on...At least thats what i was thinking. However.....

push eax
pop  anyVar

is really popping eax into anyVar? Correct?  That may be worded wrong, i dont know, but the idea i think is right.

ChrisLeslie

QuoteA lot of folks from the Ineffable All disagree with me, because I never use PROC's.  I think they are just a bunch of red tape that gets in-between the problem and the programmer.
Ratch,
Any decent program, assembler or otherwise, has to have a structure whether one uses procs, classes, objects structs or whatever it takes. If you don't use PROC's I hope you use some sort of structural aids, or else how do you put an architectural shape to your program? I would hate to debug any such program if it is more than about 10 lines long!!

Thats my opinion - Chris

hutch--

seymour,


push eax
pop  anyVar

is really popping eax into anyVar? Correct?  That may be worded wrong, i dont know, but the idea i think is right


Not exactly but its close. When you use PUSH EAX, it then becomes a value stored in stack memory, memory that is pointed to by the stack pointer ESP. This does not change the value that is still in EAX.

Here is a small test piece for you that shows you how ESP is used by the PUSH instruction.


    mov eax, 1234
    push eax

    mov edx, [esp]
    print str$(edx),13,10

    pop eax


After the PUSH EAX instruction, the value from EAX is now at the address pointed to by ESP so you have this notation [esp] .

The example just copies it back to the EDX register to display it and the value displayed is the same as the value at the memory address [esp]

The POP on exit is to ensure that stack is balanced.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ratch

ChrisLeslie,

Quote
Ratch,
Any decent program, assembler or otherwise, has to have a structure whether one uses procs, classes, objects structs or whatever it takes. If you don't use PROC's I hope you use some sort of structural aids, or else how do you put an architectural shape to your program? I would hate to debug any such program if it is more than about 10 lines long!!

Thats my opinion - Chris

     If you read the references I gave in my post, you would see that I do indeed implement a structure with respect to the stack.   I use the MASM directive STRUCT (as in structure) to do this.   Ratch


Mark Jones

Quote from: seymour_glass on March 31, 2006, 04:11:46 AM
push eax
pop  anyVar

is really popping eax into anyVar? Correct?

Here's the low-down on the stack. The "stack" is a segment of memory, pointed to by ESP, which works "backwards" from conventional thought and in a "circular" or First-In-Last-Out (FILO) arrangement. Think of the stack as literally a stack of coins - each time you push a value on, you're adding a coin to the stack. Pop takes a coin off the top. You can't pop off anything in the middle. You can however, access any value on the stack by referencing ESP plus an offset. So, say you pushed a 1, then a 2, then a 3 DWORD to the stack. The 3 is on top, so the 3 gets popped off first, then the 2, and 1. If all three are pushed on, you can get the value of 2 and 1 by referencing ESP+4 and ESP+8. Here is how the stack addressing works in "backwards" logic - each newly pushed value DECREMENTS ESP by 4 (or 2 if a WORD was pushed.) So, as the stack grows, ESP gets smaller, and as items are popped off, ESP gets larger. That's how it works "in reverse logic."

Now the things being pushed and popped can be a literal value (PUSH 1024h), a register (PUSH EAX), or a memory operand (PUSH MyVar, PUSH OFFSET szHello, PUSH DWORD PTR lpFrellit!, PUSH [EDX+ESI], etc.) Here are some questions for you to answer. Try coding a small application to test these, it will really help you learn this. A quick way to see what happens would be to load the program into a debugger like OllyDbg and press F8 to step through each instruction.

1. If EAX contains 87654321h and you PUSH EAX then POP ECX, what does ECX equal?
2. You have an integer variable "iVar" and you PUSH iVar and POP EAX. What does EAX equal?
3. You PUSH 12345678h then POP iVar. What does iVar equal?
4. If you PUSH OFFSET iVar and POP EAX, does EAX == iVAR?
5. You PUSH iVar and PUSH EAX then MOV EAX,ESP. Does EAX == iVar?
6. You PUSH iVar and PUSH EAX then MOV EAX,[ESP+4]. Does EAX == iVar?

Good luck, have fun! :toothy
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

seymour_glass

Thanks alot guys.  I got it a lil better.  As far as learning about the parameters and all that I will just have to jump into it.  Im trying to figure it out before even trying it in code, which probably isn't the best way to learn.  Im just afraid that if I start messing around with [ebx+4], im gonna get myself lost quickly.

That ASMINTRO is an excelllent resource, much better than my text...

And Mark, I havent tried those examples you gave me. I will, however, when i get back to my pc.  Although i believe that i can probably answer them without actually following it in debug,  i think that watching it will probably make a helluva difference in me grasping it.

Seymour.

ChrisLeslie

Ratch,

QuoteIf you read the references I gave in my post, you would see that I do indeed implement a structure with respect to the stack.   I use the MASM directive STRUCT (as in structure) to do this.   Ratch

Oh!  :red  -  I don't want to rekindle any old flames.
I do admire your approach using STRUCTs, and that approach had crossed my mind before but I had not pursued it. But I do also appreciate good overall program design that allows easy readability and maintenance of a program that is required to grow and improve. I'm sure you also achieve such design with your methods.

Regards

Chris

seymour_glass


Quote

5. You PUSH iVar and PUSH EAX then MOV EAX,ESP. Does EAX == iVar?
6. You PUSH iVar and PUSH EAX then MOV EAX,[ESP+4]. Does EAX == iVar?

Quote

Is it assumed that i am popping the values off? If not popped must i ret, 8? Or does this work?  I would think it would leave the stack unbalanced, which may not matter if im not returning from a call, and simply exiting...?  I dont know...?

Seymour

Ratch

seymour_glass,

     I don't know if you read carefully the pertient documentation relating the the stack and the relevant instructions, so lets review.

1) The stack is a logical segment of memory whose architecture and instruction set are optimized for 'last in first out' (LIFO) operations.  It has its own dedicated pointer register (ESP) and a stack frame register (EBP).

2) The stack grows towardS DECREASING memory addresses and shrinks towards INCREASING memory address.  That means that a PUSH will decrease the ESP value and a POP will increase the ESP value.

3) The ESP value will be at the stack memory address of the last PUSH'ed value, or the next value to be POP'ed.  In other words, a PUSH EAX is equavalent to the instruction sequence:

SUB ESP,4
MOV [ESP],EAX

Similarly, a POP  EAX is equivalent to:

MOV EAX,[ESP]
ADD ESP,4

A RET is equivalent to:

JMP [ESP]
ADD ESP,4

And a RET 8 is equivalent to:

JMP [ESP]
ADD ESP,(4+8)

Quote. You PUSH iVar and PUSH EAX then MOV EAX,ESP. Does EAX == iVar?

     No, EAX will be the stack address of the last item PUSH'ed, namely EAX.  If you wanted to load the last item you PUSH'ed, you should have coded something like MOV ECX,[ESP].  If you wanted the first item you PUSH'ed (ivar), then code MOV ECX,[ESP+4] .

QuoteYou PUSH iVar and PUSH EAX then MOV EAX,[ESP+4]. Does EAX == iVar?

     Yes, that is correct.

QuoteIs it assumed that i am popping the values off? If not popped must i ret, 8? Or does this work?  I would think it would leave the stack unbalanced, which may not matter if im not returning from a call, and simply exiting...?  I dont know...?

     You are NOT POP'ing values off with the above code sequences.  You are copying a stack address, and then the contents of a stack address into EAX.  If you code a RET, you will cause a JMP.  Is that what you want?  Since you coded two PUSH'es without any POP's,  you will need to code ADD ESP,8 to balance the stack.  Ratch