0

I don't understand why the output of the code is Ole. Shouldn't little endianness affect the push command?

global _start

  section .data
x: dd 3

section .text
_start:
  mov eax, 4
  mov ebx, 1
  mov dword[x], 0x0a656c4f
  push dword[x]
  mov ecx, esp
  mov edx, 4
  int 0x80
  mov eax,1 
  mov ebx, 0
  int 0x80

If I got it right after mov dword[x], 0x0a656c4f the memory layout is :

  0a (higher) 
  65 
  6c 
  4f (lower)

because of little endianness of x86 and x points to byte whose value is 4f. After push dword[x], there's the same picture of stack (reversed as it grows downwards) where esp points to 0a

The same question is relevant to the code when

  mov dword[x], 0x0a656c4f
  push dword[x]

is replaced with:

push dword 0x0a656c4f

Thanks.

rok
  • 9,403
  • 17
  • 70
  • 126
  • What's the point of the last part of the question? The registers `ebx`, `ecx` and `edx` contain the arguments for the `write(2)` system call. – Kerrek SB Jul 20 '13 at 15:08
  • @Kerrek SB. Sorry, fixed. – rok Jul 20 '13 at 15:10
  • Related: [Relation between endianness and stack-growth direction](https://stackoverflow.com/q/18470053) - there is none; the store part of a `push` is just a regular dword store. – Peter Cordes Feb 10 '23 at 06:14

2 Answers2

2

The stack grows downward:

Before the push:

****
****
**** <--- ESP

After push DWORD 0x0a656c4f:

****
****
****            -+
0x0A             |
0x65             ^
0x6C             |
0x4F <--- ESP   -+- write(2) four bytes from here
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
1

Remember that "little endian" (or big endian) applies to multi-byte numbers. "hello world" isn't stored "backwards" in memory. Likewise, the stack "grows downward" in the sense that push decreases esp - the memory isn't "upside down" just because it's on the stack.

A related(?) oddity to Nasm's syntax is that character constants are assumed to be in the order you write 'em. If you were searching environment variables, for example, Nasm would expect:

cmp dword [esi], 'HOME'

Other assemblers might expect:

cmp dword ptr [esi], 'EMOH'

Mostly an issue when you're "translating" from one assembler's syntax to another's...

Frank Kotler
  • 3,079
  • 2
  • 14
  • 9
  • I don't find NASM's behaviour odd, that multi-character literals go into machine code in source order. That matches the order they go into `db` or `dd`. It's MASM that's weird, reversing your string for no reason as it copies it to the output. GAS simply doesn't accept multi-character literals as integer constants in the first place. (x86 machine code uses little-endian 32-bit immediates, so immediate stores and pushes contain the data in the same order they'll store it in.) – Peter Cordes Feb 10 '23 at 06:12