Author Topic: Question about getting a word from the stack in a register  (Read 15741 times)

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Question about getting a word from the stack in a register
« on: April 08, 2013, 05:51:08 PM »
Ok so say you have a big array on the stack (like 256 bytes or something).

What happens if you want to get bytes 64, 65, 66, & 67 (for example) into a register so you can look at it.  How does that work exactly?  Since those bytes are burried deep under 63 other bytes... How does it get those?

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Question about getting a word from the stack in a register
« Reply #1 on: April 08, 2013, 07:32:37 PM »
Let's suppose stack is @ 5004H when entering this routine.  After creating procedure frame BP = 5000H & SP = 4F00H. Hense your array of 256 bytes starts @ 4F00.

To get the 67th element you take 256 - 189 = 67
Code: [Select]

enter 256, 0

mov al, [ebp - 189]

leave
ret


  ... or ...

Code: [Select]

enter 256, 0
push ebx
mov ebx, esp
add ebx, 4

mov al, [ebx + 67]

pop ebx
ret


Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Re: Question about getting a word from the stack in a register
« Reply #2 on: April 08, 2013, 07:53:16 PM »
Thank you TightCoder, I appreciate you showing me the code.  I was wondering if you could provide some comments to show me what it's doing, since I can't read assembly very well.

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Re: Question about getting a word from the stack in a register
« Reply #3 on: April 09, 2013, 04:04:10 PM »
What is "al"?  Is that a 4-byte register?

And would the bytes be arranged backwards (67, 66, 65, 64) in the register, since it's a little-endian system?

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Question about getting a word from the stack in a register
« Reply #4 on: April 09, 2013, 05:06:31 PM »
The best thing to do would be use a debugger and trace through the example to see how registers are affected.

In the meantime, I'll working on a detailed explanation that I'll have ready in a few hours.



« Last Edit: April 09, 2013, 10:24:25 PM by TightCoderEx »

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Question about getting a word from the stack in a register
« Reply #5 on: April 09, 2013, 11:15:27 PM »
CPU Stack

Address   Value
     
6FFA8 EBP-18  ESP ==>  AE2EAD08
6FFAC EBP-14  ESP+ 4   AE2EAD08
6FFB0 EBP-10  ESP+ 8   7C90E64E 
6FFB4 EBP- C  ESP+ C   7C816D4C 
6FFB8 EBP- 8  ESP+10   FFFFFFFE
6FFBC EBP- 4  ESP+14   00000009
6FFC0 EBP ==> ESP+18   0006FFF0  Orignal EBP

6FFC4

This example creates a procedure frame and then shows two common methods by which to address data on the stack.


Code: [Select]

enter 18, 0 ESP = 6FFC4
ESP = 6FFA8 & EBP = 6FFC0
mov ebx, esp
mov eax, [ebp - 10]  = 7C90E64E
mov ecx, [ebx +  8] =  " " " "

leave ESP = 6FFC4 again


See this site for an explanation of x86 registers

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Re: Question about getting a word from the stack in a register
« Reply #6 on: April 10, 2013, 05:07:54 PM »
This is totally beyond my comprehension

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: Question about getting a word from the stack in a register
« Reply #7 on: April 11, 2013, 02:44:27 AM »
Ok so say you have a big array on the stack (like 256 bytes or something).

Okay, so the example we are working with is a procedure like the following:

Code: [Select]
bigArray:
   push ebp
   mov ebp, esp
   sub esp, 256  ; allocate 256 bytes onto the stack.

   ;; Do something with the stack array here.

   mov esp, ebp
   pop ebp
   ret

What happens if you want to get bytes 64, 65, 66, & 67 (for example) into a register so you can look at it.  How does that work exactly?  Since those bytes are burried deep under 63 other bytes... How does it get those?

The reason I've done this code without the ENTER/LEAVE instructions is to make things a bit more clear as to what is going on. The most important thing to note is that the stack actually grows down. In the above example, when we have allocated the memory we do so with a  SUB instruction. At that point, EBP is at the "Top of Stack" and ESP is at the "Bottom of Stack". When TightCoderEx mentions "256 - 189 = 67" he's actually addressing the variable location against the "Top of Stack" so he's counting backwards. To access the bytes of our array, it's a bit easier to just use the "Bottom of Stack" with ESP.

Code: [Select]
bigArray:
   push ebp
   mov ebp, esp
   sub esp, 256  ; allocate 256 bytes onto the stack.

   ;; Place byte 64 into AL and byte 65 into BL
   mov al, byte [esp + 64]
   mov bl, byte [esp + 65]

   ;; Now place the value of AL into 66 and the value of BL into 67
   mov byte [esp + 66], al
   mov byte [esp + 67], bl

   mov esp, ebp
   pop ebp
   ret

I suggest you stick to using EBP for procedure arguments and ESP for variables. It's a very common convention and it'll make things much easier. There was a similar discussion over at ASM Community that might help you. You should check it out:

http://www.asmcommunity.net/board/index.php?topic=30275.0 - The Stack

About Bryant Keller
bkeller@about.me

Offline hhh3h

  • Jr. Member
  • *
  • Posts: 41
Re: Question about getting a word from the stack in a register
« Reply #8 on: April 15, 2013, 05:02:15 PM »
Thank you for the detailed explainations. I particularly found Franks comment on the Asm Community very useful.

I need to think about this info for a while. I might have to asking questions later.