2
votes

I've been experimenting with assembly in Linux with NASM, so that I could understand the loader.s script on OSDev.

One thing that I found interesting was the assembly generated when a variable was declared with dd. I ran some tests and I've put the output below. Essentially, I'm just allocating different numbers and seeing what assembly is generated in the object file (not the executable).

$ cat test1.s
global _start

section .text
    dd 0x0

_start:
    mov eax, 1
    mov ebx, 0
    int 80h

$ nasm -f elf test1.s ; objdump -d test1.o

test1.o:     file format elf32-i386


Disassembly of section .text:

00000000 <_start-0x4>:
   0:   00 00                   add    %al,(%eax)
    ...

00000004 <_start>:
   4:   b8 01 00 00 00          mov    $0x1,%eax
   9:   bb 00 00 00 00          mov    $0x0,%ebx
   e:   cd 80                   int    $0x80

.

$ cat test2.s
global _start

section .text
    dd 0x0
    dd 0x5

_start:
    mov eax, 1
    mov ebx, 0
    int 80h

$ nasm -f elf test2.s ; objdump -d test2.o

test2.o:     file format elf32-i386


Disassembly of section .text:

00000000 <_start-0x8>:
   0:   00 00                   add    %al,(%eax)
   2:   00 00                   add    %al,(%eax)
   4:   05 00 00 00 b8          add    $0xb8000000,%eax

00000008 <_start>:
   8:   b8 01 00 00 00          mov    $0x1,%eax
   d:   bb 00 00 00 00          mov    $0x0,%ebx
  12:   cd 80                   int    $0x80

.

$ cat test3.s
global _start

section .text
    dd 0x0
    dd 0x5
    dd 0xf

_start:
    mov eax, 1
    mov ebx, 0
    int 80h

$ nasm -f elf test3.s ; objdump -d test3.o

test3.o:     file format elf32-i386


Disassembly of section .text:

00000000 <_start-0xc>:
   0:   00 00                   add    %al,(%eax)
   2:   00 00                   add    %al,(%eax)
   4:   05 00 00 00 0f          add    $0xf000000,%eax
   9:   00 00                   add    %al,(%eax)
    ...

0000000c <_start>:
   c:   b8 01 00 00 00          mov    $0x1,%eax
  11:   bb 00 00 00 00          mov    $0x0,%ebx
  16:   cd 80                   int    $0x80

.

$ cat test4.s
global _start

section .text
    dd 0x0
    dd 0x5
    dd 0xf
    dd 0x16

_start:
    mov eax, 1
    mov ebx, 0
    int 80h

$ nasm -f elf test4.s ; objdump -d test4.o

test4.o:     file format elf32-i386


Disassembly of section .text:

00000000 <_start-0x10>:
   0:   00 00                   add    %al,(%eax)
   2:   00 00                   add    %al,(%eax)
   4:   05 00 00 00 0f          add    $0xf000000,%eax
   9:   00 00                   add    %al,(%eax)
   b:   00 16                   add    %dl,(%esi)
   d:   00 00                   add    %al,(%eax)
    ...

00000010 <_start>:
  10:   b8 01 00 00 00          mov    $0x1,%eax
  15:   bb 00 00 00 00          mov    $0x0,%ebx
  1a:   cd 80                   int    $0x80

My question is why are we adding things to the eax register initially, and then modifying other registers like edx and esi as the data grows? Allocating that data shouldn't use registers, and it especially shouldn't be adding them. And why can I never see the correct variable being put into the register (the answer to the first question might answer this)? For example, I see the instruction add $0xb8000000,%eax when I'm allocating 0x5, but there's no 0x5 in that instruction.

2

2 Answers

5
votes

When you declare a DWORD with dd 0, it is literally just placing 4 bytes of zeros in the output binary at that point. When you are disassembling the binary, it is interpretting that as code (when you intended it to be data). It happens that the opcodes for add %al,(%eax) are 00 00

0
votes

You declared those variable in .text section and that's why those addition are taking place , to get rid-of that ,just declare .data section and those additional addition will not take place .