asm

Assembly

Dalla pagina http://www.tortall.net/projects/yasm/manual/html/objfmt-elf32.html

The Executable and Linkable Object Format is the primary object format for many operating systems including FreeBSD or GNU/Linux. It appears in three forms:

Shared object files (.so)
Relocatable object files (.o)
Executable files (no convention)

Yasm only directly supports relocatable object files. Other tools, such as the GNU Linker ld, help turn relocatable object files into the other formats. Yasm supports generation of both 32-bit and 64-bit ELF files, called elf32 and elf64. A generic interface to both is also provided, elf, which selects between elf32 and elf64 based on the target machine architecture

Dalla precedente definizione si comprendono i comandi per assemblare:

yasm -f elf32 -o first.o first.asm
ld -o first first.o
./first

Analisi di un semplice programma per iniziare

section .text
	global _start ; Per il linker ld
_start
	mov eax,4 ; chiamata al kernel: write
	mov ebx,1 ; dove scrivere: stdout
	mov ecx,message ; stringa
	mov edx,message_lenght ; numero caratteri
	int 0x80 ; chiamata al kernel !!!
	mov eax,1 ; chiamata al kernel : exit
	int 0x80 ; chiamata al kernel !!!

section .data
	message db "Assembly rules!",10
	message_lenght equ $-message

Le prime due righe indicano dove inizia il programma.
Dopo l’ etichetta “_start” ci sono le istruzioni:
le prime 4 istruzioni inseriscono nei registri della CPU alcuni dati (poi vedremo cosa sono);
dopo c’è l’ istruzione int 0x80 che ha un significato molto forte:
definizione http://www.linfo.org/int_0x80.html e spiegazioni:

int means interrupt, and the number 0x80 is the interrupt number. An interrupt transfers the program flow to whomever is handling that interrupt, which is interrupt 0x80 in this case. In Linux, 0x80 interrupt handler is the kernel, and is used to make system calls to the kernel by other programs.

The kernel is notified about which system call the program wants to make, by examining the value in the register %eax (gas syntax, and EAX in Intel syntax). Each system call have different requirements about the use of the other registers. For example, a value of 1 in %eax means a system call of exit(), and the value in %ebx holds the value of the status code for exit().

Dopo il primo interrupt c’è un altro mov seguito da un int: è proprio la chiamata di sistema per exit(), impostata con il registro %eax che contiene il valore 1.

Tornando al primo blocco di istruzioni mov, vediamo che %eax contiene 4: adesso capiamo che questo registro indica al kernel quale operazione eseguire; in questo caso 4 indica una write().

Il significato del numero di chiamata al kernel presente nel registro %eax risiede nel file /usr/include/asm/unistd.h (presente nel pacchetto linux-libc-dev di debian):

/*
* This file contains the system call numbers.
*/

#define __NR_restart_syscall      0
#define __NR_exit                 1
#define __NR_fork                 2
#define __NR_read                 3
#define __NR_write                4
#define __NR_open                 5
#define __NR_close                6
#define __NR_waitpid              7
#define __NR_creat                8
#define __NR_link                 9
......

cercare syscall o system call per ulteriori approfondimenti.

In coda al listato c’è la sezione .data: questa contiene i dati statici.

  • la variabile “message” viene dichiarata come db (data bytes) e viene inizializzata con una stringa seguita da “,10”, ossia il numero 10 viene concatenato in coda alla stringa. Il numero 10 rappresenta il carattere di “a capo”, così che la stringa visualizzata in output sia ben formattata.
  • la variabile “message_lenght” viene impostata tramite la direttiva equ alla lunghezza della stringa precedente. Ciò si ottiene a partire dalla posizione corrente del programma ($) meno la posizione di “message”: dalla sottrazione si ottiene la lunghezza di “message”.

Disassemblare

Il disassembler di nasm fornisce un output poco leggibile.
Però c’è un altro strumento:

objdump -d first

fornisce un output in un formato diverso da quello usato per scrivere il codice: le istruzioni mov sono invertite, i numeri sono esadecimali, e le etichette sono sostituite dalle locazioni di memoria; è la sintassi AT&T.
Per controllare la sintassi dell’ output si può usare lo switch -M:

objdump -d -M intel first
# oppure
objdump -d -M intel-mnemonic first

first:     file format elf32-i386

Disassembly of section .text:

08048080 <_start>:
 8048080:	b8 04 00 00 00       	mov    eax,0x4
 8048085:	bb 01 00 00 00       	mov    ebx,0x1
 804808a:	b9 a0 90 04 08       	mov    ecx,0x80490a0
 804808f:	ba 10 00 00 00       	mov    edx,0x10
 8048094:	cd 80                	int    0x80
 8048096:	b8 01 00 00 00       	mov    eax,0x1
 804809b:	cd 80                	int    0x80

Riferimenti

Vedere http://www.cin.ufpe.br/~if817/arquivos/asmtut/index.html per ulteriori informazioni.
http://www.giobe2000.it/tutorial/Home.asp
Un testo completo sul linguaggio assembly si trova sul sito http://www.drpaulcarter.com/pcasm/: ecco il PDF Assembly

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...