NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: hhh3h 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?
-
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
enter 256, 0
mov al, [ebp - 189]
leave
ret
... or ...
enter 256, 0
push ebx
mov ebx, esp
add ebx, 4
mov al, [ebx + 67]
pop ebx
ret
-
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.
-
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?
-
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.
-
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.
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 (http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html) site for an explanation of x86 registers
-
This is totally beyond my comprehension
-
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:
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.
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
-
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.