0

I am trying to teach myself assembly and was having some difficult with the interactions between the stack and accessing it. I am using a x86 64 bit system and was doing a simple program that pushes 5 and 2 into the stack (in that order) and then call a function. So, if the word size is 2 bytes then I should be able to get to 2 by doing [esp+2] account for the return address. However, I am getting 0 because when I use edg and step through, the value (by moving it into a register) is 00000002000000 so I can access it with [esp+8] and then 5 with [esp+16] however, that would mean that a word size is 4? So does that mean that the size of the word depends on bit of the system? What about even just the register used? Instead is it because the size for each segment of the stack is 8 bytes on a 64 bit system?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Ford Smith
  • 195
  • 1
  • 1
  • 7
  • A "word" is always 2 bytes in x86 terminology. But that's not the "word size" or register width. **"word size" is not a useful concept for x86-64**; it natively supports operand-sizes of 1, 2, 4, and 8 bytes (and 16, 32, and 64 with SSE, AVX, and AVX512 in vector registers). Actual data buses are wider than integer registers, etc. etc. – Peter Cordes May 31 '19 at 01:55
  • Possible duplicate [What are the calling conventions for UNIX & Linux system calls on i386 and x86-64](https://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-i386-and-x86-6) – David C. Rankin May 31 '19 at 03:23
  • @David C. Rankin they are 2 entirely different questions. This is not about passing parameters to a function, its about the different sizes of the registers and stack per segment from machine to machine... – Ford Smith May 31 '19 at 03:49
  • That is why it is listed as a "Possible duplicate" and no Close-vote was made. It addresses the x86_64 calling convention explicitly, e.g. `RDI, RSI, RDX, RCX, R8, and R9, etc...` which is relevant to your `"I am using a x86 64 bit system and was doing a simple program that pushes 5 and 2 into the stack (in that order) and then call a function."` That is not how values are passed on x86 64. – David C. Rankin May 31 '19 at 03:56

1 Answers1

3

Instead is it because the size for each segment of the stack is 8 bytes on a 64 bit system?

Yes.

When you push these things then call a function, this is your stack:

+-----------------+
|        5        | RSP+0x10
+-----------------+
|        2        | RSP+0x08
+-----------------+
|   Return Addr   | RSP+0x00
+-----------------+

Likewise, on a 32-bit system you're looking at this for your stack:

+-----------------+
|        5        | ESP+0x08
+-----------------+
|        2        | ESP+0x04
+-----------------+
|   Return Addr   | ESP+0x00
+-----------------+

As an aside, remember that the 64-bit registers start with an R (RSP, RAX, etc). Also, depending on your operating system you're likely to be incorrectly passing parameters via the stack. 64-bit systems use registers for the first N parameters then the stack from then on. The registers are different depending on whether you're passing integers/pointers or floating point. For your purposes, with SystemV the first 6 are passed via RDI, RSI, RDX, RCX, R8 and R9 (in that order). 64-bit Windows uses RCX, RDX, R8 and R9 for the first 4 (in that order). This isn't important now while you're learning, but it'll become increasingly important as you start calling into other modules/OS APIs.

Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138