lunedì 5 novembre 2012

Primi passi in Assembler su Linux


piu' che altro per divertimento ho provato a riscrivere qualcosa in assembler..era dai tempi del DOS e di Int 21h che non usavo piu' l'assembler
E' curioso ritrovare che anche Linux come Dos usa un interrupt (80h) per la gestione del sistema ed e' anche curioso di come si possano usare le chiamate alle funzioni C (in questo caso printf) dall'Assembler (di solito e' il linguaggio di piu' alto livello che sfrutta quello di livello piu' basso)

Tutti gli esempi sono compilati con nasm

Il primo esempio stampa una scritta a video usando l'Int 80h
Per la compilazione si devono dare i seguenti comandi
nasm -f elf32 scrivi.asm
ld -o scrivi scrivi.o

scrivi.asm
-------------------------------------------------------
global _start

section .text
_start:
    mov eax,4
    mov ebx,1
    mov ecx,messaggio
    mov  edx,lunghezza
    int 80h

    mov eax,1
    mov ebx,0
    int 80h

section .data
    messaggio: db 'Hello ',0x0a
    lunghezza: equ $-messaggio


-------------------------------------------------------
come output si ha
Hello

Per il secondo esempio si usa invece la chiamata esterna printf per stampare il valore di una variabile

In questo caso la catena di compilazione e' differente per venire incontro alla chiamata esterna che e' risolta da gcc
nasm -f elf32 -l scrivi2.lst scrivi2.asm
gcc -o scrivi2 scrivi2.o

scrivi2.asm
-------------------------------------------------------
 extern printf

section .text

    global main
main:
    push ebp
    mov ebp,esp


    push dword [a]
    push dword formato
    call printf

    add esp,12

    mov esp,ebp
    pop ebp

    mov eax,0
    ret

section .data
    a: dd 5
    formato: db "a=%d",10,
0

-------------------------------------------------------
come output si ha
a=5

Molto simile al precedente il terzo esempio mostra un ciclo

nasm -f elf32 -l scrivi3.lst scrivi3.asm
gcc -o scrivi3 scrivi3.o

scrivi3.asm
-------------------------------------------------------
 extern printf

section .text

    global main
main:
    push ebp
    mov ebp,esp

    mov ebx,10
gira:
    push ebx
    push dword formato
    call printf
    dec ebx
    jnz gira
  

    mov esp,ebp
    pop ebp

    mov eax,0
    ret

section .data
    formato: db "ciclo=%d",10,0

-------------------------------------------------------

produce come output
ciclo=10
ciclo=9
ciclo=8
ciclo=7
ciclo=6
ciclo=5
ciclo=4
ciclo=3
ciclo=2
ciclo=1