Αλλαγή γραμματοσειράς
Ημερομηνία Τρί Σεπ 17, 2019 7:27 pm
foss.aueb.gr
Αρχική Κοινότητας Foss Aueb Tutorials - HowTo's - Articles

Tutorials - HowTo's - Articles

Assembly programming in linux using nasm

Tutorials, How-to's, articles and other stuff by foss.aueb members

Assembly programming in linux using nasm

Δημοσίευσηαπό TNT » Τετ Φεβ 24, 2010 10:06 am

Το παρακάτω αποτελεί την εισαγωγή σε μια σειρά από tutorials για assembly programming σε Linux που θα αναρτήσω εδώ.
Ελπίζω να βοηθήσω όσους δεν γνωρίζουν και δεν έχουν ασχοληθεί με assembly αλλά και όσους ασχολήθηκαν αλλά κάποια πράγματα δεν είναι ξεκάθαρα.
Δεν θα ξεκινήσω με την κλασική θεωρία registers κλπ. Θα μπω κατευθείαν στο θέμα και θα εξηγήσω ένα απλό πρόγραμμα σε assembly, το κλασικό hello world!
(σχόλια, κριτικές καλοδεχούμενες ;) )

Μέρος 1
Κάθε πρόγραμμα σε assembly χωρίζεται σε 3 τμήματα, .data, .text και .bss
Για την ώρα στο 'Hello world' παράδειγμα θα δούμε μόνο τα τμήματα .data και .text
Τα τμήματα τα δηλώνουμε με την εντολή section. π.χ. section .text

Το τμήμα .data είναι το τμήμα όπου δηλώνονται, αρχικοποιούνται "μεταβλητές". Δεν είναι μεταβλητές με τη κλασική, συνηθισμένη έννοια.
Γιατί κατά τη διάρκεια που τρέχει το πρόγραμμα οι μεταβλητές που έχουν δηλωθεί στο τμήμα .data δεν μπορούν να αλλάξουν, να μεταβληθούν τα περιεχόμενά τους

Θα δούμε στο παράδειγμα την εντολή equ. Με την equ δηλώνονται σταθερές

Στο τμήμα .text είναι το τμήμα στο οποίο γράφουμε τον assembly κώδικα
Το πρώτο πράγμα που κάνει κανείς αφού δηλώσει το τμήμα .text είναι η δήλωση global _start.
Με αυτό τον τρόπο δηλώνουμαι που ξεκινάει η εκτέλεση του προγράμματός μας. Κάτι σαν τη main() στη C ή στη C++

To db παρακάτω που δηλώνουμε το message σημαίνει define byte, δηλώνουμε δηλαδή μια ακολουθία από bytes.

Hello World sample - hello.asm
Κώδικας: Επιλογή όλων
section   .data
   message   db   'Hello, world!',10 ;10 = αλλαγή γραμμής = \n
   length   equ   14 ;μήκος γραμματοσειράς message, υπάρχει πιο κομψός τρόπος να δηλώσουμε το μήκος, θα το δούμε αργοτέρα..

section   .text
    global _start

_start:
   mov   edx,length    ;αποθήκευσε στο edx register το μήκος της γραμματοσειράς message
   mov   ecx,message ;αποθήκευσε στο ecx register τη γραμματοσειρά message
   mov   ebx,1           ;αποθήκευσε το 1 στο register ebx, δηλώνουμαι εδώ ότι το μήνυμα θα "τυπωθεί" στην standard έξοδο
   mov   eax,4           ;αποθήκευσε το 4 στο register eax, το 4 αντιστοιχεί στην κλήση συστήματος sys_write, με λίγα λόγια εδώ λέμε στο πρόγραμμα να "τυπώσει"
   int   0x80            ;με την συγκεκριμένη εντολή καλούμε το πυρήνα γίνεται αλλαγή από user mode σε kernel mode και εκτελούνται οι κλήσεις συστήματος

   mov   eax,1 ;αποθήκευσε το 1 στο register eax, το 1 αντιστοιχεί στην κλήση συστήματος sys_exit - έξοδος από το πρόγραμμα, όπως η exit(0) της C
   int   0x80 ; κάλεσε τον πυρήνα και εκτέλεσε την sys_exit


Ευχαριστώ. :)

to be continued..
Τελευταία επεξεργασία απο TNT την Πέμ Φεβ 25, 2010 9:19 am, επεξεργάστηκε 1 φορές συνολικά.
who am i?
Άβαταρ μέλους
TNT
Open Member
 
Δημοσ.: 119
Εγγραφη: Κυρ Δεκ 20, 2009 2:23 pm

Re: Assembly programming in Linux using nasm

Δημοσίευσηαπό TNT » Πέμ Φεβ 25, 2010 9:13 am

Μέρος 2
Compiling and linking

Αφού εγκαταστήσετε το nasm (ανάλογα με τη διανομή που έχει ο καθένας),

1. ανοίγουμε ένα terminal παράθυρο, βεβαιωνόμαστε οτι είμαστε στο φάκελο που βρίσκεται το hello.asm αρχείο μας. (διαφορετικά cd.... κλπ)

2. Πληκτρολογούμε: nasm -f elf hello.asm (elf είναι το format για τα executables του linux, κάτι αντίστοιχο με το exe των Windows)

3. Παράγεται ένα object file hello.o

4. Για να δημιουργήσουμε το executable πληκτρολογούμε: ld hello.o -o hello

5. Δεν μένει παρά να εκτελέσουμε το πρόγραμμα μας δίνωντας την εντολή ./hello, για να δούμε να τυπώνεται το μήνυμα Hello, World!

Ευχαριστώ. :)

to be continued..
who am i?
Άβαταρ μέλους
TNT
Open Member
 
Δημοσ.: 119
Εγγραφη: Κυρ Δεκ 20, 2009 2:23 pm

Re: Assembly programming in Linux using nasm

Δημοσίευσηαπό TNT » Κυρ Φεβ 28, 2010 12:57 pm

Μέρος 2b
Compiling and linking in 64bit

Αν έχετε 64bit επεξεργαστή όταν θα κάνετε link το object file hello.o
ο linker θα παραπονεθεί με ένα μήνυμα σαν και αυτό:
'ld: i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output'

Επομένως θα πρέπει να πούμε στον linker να χρησιμοποιήσει format για το executable για 32bit
επεξεργαστή.

ld -melf_i386 HelloWorld.o -o HelloWorld

Άλλα format είναι: elf_x86_64 i386linux
who am i?
Άβαταρ μέλους
TNT
Open Member
 
Δημοσ.: 119
Εγγραφη: Κυρ Δεκ 20, 2009 2:23 pm

Re: Assembly programming in Linux using nasm

Δημοσίευσηαπό TNT » Κυρ Φεβ 28, 2010 1:00 pm

Μέρος 3
writing to file a string

Δεν θα μπω ούτε σε αυτό το μέρος 3 στους registers.
Το καθυστερώ μέχρι να δούμε μερικά βασικά παραδείγματα.
Επομένως θα δούμε ακόμα ένα παράδειγμα κώδικα.
Το συγκεκριμένο παράδειγμα ανοίγει ένα αρχείο, το όνομα το διαβάζει από το console ως argument (command line).
Γράφουμε το Hello, World! στο αρχείο και το κλείνουμε.

Write2File.asm
Κώδικας: Επιλογή όλων
section .data
   message     db   'Hello, world!',10
   length  equ   14

section   .text
    global _start

_start:
   pop   ebx      ; arguments count - like argc in C
   pop   ebx      ; first argument - program's name like argv[0] in C
   pop   ebx      ; second argument - we want a filename - argv[1]

   mov   eax,8      ; sys_creat, αποθήκευσε στον register eax τη τιμή 8
   mov   ecx,00644Q   ; permissions για το αρχείο, 644 - octal μορφή
            ; owner: read and write
            ; group: only read
            ; others: only read
   int   80h      

   test   eax,eax      ; ελέγχουμε αν το file handle στον eax είναι έγκυρο
   js   exit      ; θα το εξηγήσω σε άλλη ενότητα
   call   write2file   ; καλούμε τη function write2file

exit:
   mov   eax,1   
   int   80h   

; write a string to a file
write2file:
   mov   ebx,eax      ; μετέφερε το file descriptor-handle στο ebx
            ; δηλώνουμαι εδώ ότι το μήνυμα θα "τυπωθεί" στo file handle, κάτι αντίστοιχο κάναμε και στο προηγούμενο
            ; παράδειγμα στο μέρος 1, όπου αποθηκεύοντας το 1 στον ebx τυπώσαμε στην οθόνη.

   mov   eax,4      ; sys_write system call

   mov   ecx,message
   mov   edx,length
   int   80h

   mov   eax,6      ; καλούμε τη sys_close για να κλείσουμε το αρχείο (εφόσον το file handle είναι στον ebx, που είναι..)
   int   80h
   ret


Τα arguments του προγράμματος αποθηκεύονται στη stack.
Γι αυτό και χρησιμοποιούμε την εντολή pop για να τα πάρουμε αποθηκεύοντας τα στο register ebx.
Τρόπος εκτέλεσης αφού γίνει compile και link: ./write2file test.txt

Ευχαριστώ. :)

to be continued..
who am i?
Άβαταρ μέλους
TNT
Open Member
 
Δημοσ.: 119
Εγγραφη: Κυρ Δεκ 20, 2009 2:23 pm

Re: Assembly programming in Linux using nasm

Δημοσίευσηαπό TNT » Τρί Μαρ 09, 2010 11:03 am

Μέρος 4

Θα ξεκινήσω με τους βασικούς registers της αρχιτεκτονικής intel.
Η αρχιτεκτονική i386 έχει 8 γενικού σκοπού 32bit registers.
Η παρουσίαση παρακάτω είναι σύντομη, για οποιαδήποτε απορία ρωτήστε εδώ:
http://foss.aueb.gr/forum/viewtopic.php?f=32&t=176

EAX - accumulator
Όλοι οι υπολογισμοί πραγματοποιούνται στον EAX.

EBX - base register
γενικού σκοπού.

ECX - count register
Σκοπός της υπαρξής του είναι να μετράει! πχ. σε loops
Παίζει το ρόλο του i όπως σε ένα loop της C. for(int i=0;i<10;i++)...


EDX - data register
O EDX είναι σαν extension στον EAX.
Στον EDX αποθηκεύουμε data που σχετίζονται με τους υπολογισμούς που γίνονται στον EAX.


ESI - source index
Χρησιμοποείται στους υπολογισμούς που αφορούν data.
Είναι ένας pointer για διάβασμα data από τη μνήμη.


EDI - destination index
Χρησιμοποείται στους υπολογισμούς που αφορούν data.
Είναι ένας pointer για γράψιμο data στη μνήμη.


EBP - base pointer, ESP - stack pointer
Χρησιμοποιούνται στη κλήση μεθόδων-συναρτήσεων,
αποθήκευση παραμέτρων στη stack, διαχείριση της stack κλπ.


Ευχαριστώ. :)

to be continued..
who am i?
Άβαταρ μέλους
TNT
Open Member
 
Δημοσ.: 119
Εγγραφη: Κυρ Δεκ 20, 2009 2:23 pm


Επιστροφή στην Tutorials - HowTo's - Articles

cron
foss.aueb.gr

Μελη σε συνδεση

Συνολικά υπάρχει 1 μέλος συνδεδεμένο: 0 εγγεγραμμένο, 0 κρυφοί και 1 επισκέπτης (με βάση τα μέλη που έχουν συνδεθεί τα τελευταία 5 λεπτά)
Περισσότερα μέλη σε σύνδεση 167 την Κυρ Οκτ 02, 2016 2:55 am

Μέλη σε αυτή την Δ. Συζήτηση : Δεν υπάρχουν εγγεγραμμένα μέλη και 1 επισκέπτης

Γενέθλια

Κανένα μέλος δεν έχει γενέθλια σήμερα