0

I am learning Assembly and I found something I don't understand clearly.

If I have code like this

section .data
    var dw 0x10, 0x20, 0x30

section .text
    ; ...
    mov edx, dword 0x12345678
    mov [var], edx
    ; ...

I do know already, that result will be

[var] = 0x5678
[var + 2] = 0x1234

I just don't know what happened inside.

Why was dx = 0x5678 stored as the first element and not the second? And after this half is stored, does the first half of edx suddenly becomes word instead of double word?

How it works at all, if I attempt to put a bigger number into memory than it is reserved (let's say 256 into var_b resb 1)?

Thank you.

stefanobaghino
  • 11,253
  • 4
  • 35
  • 63
SevO
  • 303
  • 2
  • 11

1 Answers1

3

Your code stores 0x12345678 in edx, and then copy the value from edx in place where the var is placed. Lowest byte(8 bit) goes first when they are storied in memory from a register, because x86 processors are little endian.

Code compiled by nasm:

global _start

section .data
    var dw 0x10, 0x20, 0x30

section .text
_start:

mov edx, dword 0x12345678
mov [var], edx

; quit the program
mov eax, 1      ; sys_exit system call
push dword 0        ; program return value
push eax
int 0x80        ; call the kernel

Debugger:

(gdb) b _start 
Breakpoint 1 at 0x8048080
(gdb) r
Starting program: /home/ssssssssssssssss/test 

Breakpoint 1, 0x08048080 in _start ()
(gdb) disassemble 
Dump of assembler code for function _start:
=> 0x08048080 <+0>: mov    edx,0x12345678
   0x08048085 <+5>: mov    DWORD PTR ds:0x804908c,edx
End of assembler dump.
(gdb) x/4x 0x804908c
0x804908c:  0x10 0x0 0x20 0x0
(gdb) si
0x08048085 in _start ()
(gdb) disassemble 
Dump of assembler code for function _start:
   0x08048080 <+0>: mov    edx,0x12345678
=> 0x08048085 <+5>: mov    DWORD PTR ds:0x804908c,edx
End of assembler dump.
(gdb) i r
eax            0x0  0
ecx            0x0  0
edx            0x12345678   305419896
ebx            0x0  0
esp            0xbfffee70   0xbfffee70
ebp            0x0  0x0
esi            0x0  0
edi            0x0  0
eip            0x8048085    0x8048085 <_start+5>
eflags         0x202    [ IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x0  0
(gdb) si
0x0804808b in ?? ()
(gdb) x/4x 0x804908c
0x804908c:  0x78    0x56    0x34    0x12
(gdb) 

objdump:

test:     file format elf32-i386


Disassembly of section .text:

08048080 <_start>:
 8048080:       ba 78 56 34 12          mov    edx,0x12345678
 8048085:       89 15 8c 90 04 08       mov    DWORD PTR ds:0x804908c,edx

https://github.com/tigertv/stackoverflow-answers

TigerTV.ru
  • 1,058
  • 2
  • 16
  • 34
  • I am sorry but this debugger message didn't help me at all, i asked how the mechanism works if i store a number with bigger size into reserved memory of smaller size. If `edx = 0x12345678`, i know that first 16 bits by Little endian are stored first. Problem is that i don't know how it continues. I have `[var+0] = 0x5678` and `edx = 0x12345678` and i don't know how it is rotated or shifted or what so `0x1234` end's up in `[var+2]` if `edx` hasn't changed at all. – SevO Feb 21 '18 at 06:08
  • @SevO: [var] points on a byte, I think you get it if you debug the following: `xor edx,edx mov edx, [var] xor edx,edx mov dx, [var] xor edx,edx mov dl, [var] xor edx,edx mov dh, [var]` – TigerTV.ru Feb 21 '18 at 10:00
  • @SevO:Do you use debugger or just think how it will work? – TigerTV.ru Feb 21 '18 at 10:06
  • I am using a program which can display all registers, but i was confused how it is if you want to store `edx` into array of `word` because you want to store `32b` into `16b` and `16b`.. i was confused by order of storing but I think I do understand it now. Thank you for you effort :) – SevO Feb 21 '18 at 10:24
  • You can't store `32b` in `16b`, [var] points on an address in memory where a byte is placed. When you'll read from this address, size of reading bytes will depend on size of destination register – TigerTV.ru Feb 21 '18 at 10:29
  • Misunderstanding, I meant to store content of register `edx` (which is 32 bits) into array of `word`s (where one element has 16 bits). It is stored as `[var + 0] = dx` and since only half of register was stored, other half is stored into `[var + 2]`. This was what i had not understood, but it makes sense now. – SevO Feb 21 '18 at 10:35
  • I'm happy that you understand now – TigerTV.ru Feb 21 '18 at 10:38