Miłosz Grzegorzewski

43
Witaj świecie dla różnych kompilatorów (NASM, FASM, Gnu As). Assembler - różnice w składni Intel i AT&T. Miłosz Grzegorzewski

description

Miłosz Grzegorzewski. Witaj świecie dla różnych kompilatorów (NASM, FASM, Gnu As). Assembler - różnice w składni Intel i AT&T. 1. Opis NASM oraz „Hello world” 2. Opis FASM oraz „Hello world” 3. Opis GNU Assembler oraz „Hello world” 4. Różnice w składni Intela i AT&T. Agenda. - PowerPoint PPT Presentation

Transcript of Miłosz Grzegorzewski

Page 1: Miłosz Grzegorzewski

Witaj świecie dla różnych kompilatorów (NASM, FASM, Gnu As). Assembler - różnice w składni

Intel i AT&T.

Miłosz Grzegorzewski

Page 2: Miłosz Grzegorzewski

Agenda

1. Opis NASM oraz „Hello world” 2. Opis FASM oraz „Hello world” 3. Opis GNU Assembler oraz „Hello world”4. Różnice w składni Intela i AT&T.

Page 3: Miłosz Grzegorzewski

NASMNetwide Assembler to wolnodostępny asembler dla

języka Asembler x86.Został stworzony przez Simona Tathama jako

alternatywa dla GNU Assembler z pakietu binutils, który został zaprojektowany jako back-

end dla kompilatorów, w związku z czym nie posiada odpowiedniego interfejsu użytkownika.

Obecnie NASM rozwijany jest w ramach SourceForge.

Składnia języka używana przez NASM jest składnią Intela z niewielkimi modyfikacjami.

NASM jest dostępny na zasadach GNU General Public License oraz na własnej licencji.

Page 4: Miłosz Grzegorzewski

NASM – hello world na windowsieorg 100h

%define cr 13%define lf 10%define nwln cr, lf

section .dataHelloWorld db "Hello World!", nwln, '$'

section .textglobal _start

_start:mov ah, 9mov dx, HelloWorldint 21hmov ax, 4C00hint 21h

Page 5: Miłosz Grzegorzewski

NASM – hello world na windowsie

org 100h;określa gdzie dany program oczekuje, że zostanie

załadowany do pamięci

Page 6: Miłosz Grzegorzewski

NASM – hello world na windowsie

section .dataHelloWorld db "Hello World!", nwln, '$'

segment o nazwie ".data".

tekst to nazwa naszej zmiennej, db to typ naszej zmiennej (db - 1 bajt)

nwln; to wartość początkowa dla naszej zmiennej.

znakiem $; oznaczamy koniec naszego ciągu (dla migrantów z C/C++ -

jest to odpowiednik znaku '\0').

Page 7: Miłosz Grzegorzewski

NASM – hello world na windowsiemov ah, 9

mov dx, HelloWorldint 21h

Instrukcja int wywołuje podprogram obsługi przerwania o

podanym numerze .Podprogram ów wywołuje odpowiednią funkcję o numerze podanym w rejestrze ah (wcześniej nadaliśmy temu rejestrowi wartość 9, więc instrukcja int 21h wywołała funkcję numer 9

przerwania numer 21 w zapisie szesnastkowym). Wywołana w tym przypadku funkcja wyświetla w konsoli ciąg

znaków, ;którego adres znajduje w rejestrze dx

Page 8: Miłosz Grzegorzewski

NASM – hello world na windowsie

mov ax, 4C00hint 21h

Wychodzimy z programu, wywołujemy funkcję przerwania 21 o numerze 4C00h. Odpowiada ona

za zakończenie działania programu i oddanie sterowania do systemu.

Page 9: Miłosz Grzegorzewski

NASM – hello world na windowsie

Kompilacja:

nasm plik_asembler.asm -o plik_wynikowy

Page 10: Miłosz Grzegorzewski

NASM – hello world na linuxiesegment .datamsg db "Hello World!", 0Ah ; umieszcza w segmencie danych

; ciąg znaków zakończony znakiem końca linii segment .text global _start _start: mov eax, 4 mov ebx, 1 mov ecx, msg ; adres pierwszego znaku do wyświetlenia mov edx, 14 ; liczba znaków do wyświetlenia int 80h ; wywołanie funkcji systemowej wyświetlającej ciąg

; znaków o danej długości ; wyjscie z programu mov eax, 1 xor ebx, ebx int 0x80; KONIEC PROGRAMU

Page 11: Miłosz Grzegorzewski

NASM – hello world na linuksie

Kompilacja:nasm -f elf hello.asm

Linkowanie do postaci wykonywalnej:ld hello.o -o hello

Uruchomienie:./hello

Page 12: Miłosz Grzegorzewski

FASMFASM – flat assembler – szybki i wydajny asembler dla

systemów: DOS, Windows oraz kompatybilnych z Uniksem (Linux, BSD).

Opracowany przez Tomasza Grysztara. Program darmowy i wolnym, oparty o licencję BSD z zastrzeżeniem, że nie może być zmieniona na inną (np. GNU GPL – formalnie licencja

BSD nie stawia takiego wymogu). Obsługuje wszystkie instrukcje procesorów 8080-80486/Pentium wraz z

rozszerzeniami MMX, 3DNow!, SSE, SSE2, SSE3, SSSE3, SSE4, AVX, XOP oraz AVX2. Ponadto rozpoznaje instrukcje

ze zbiorów VMX, SVM, SMX, XSAVE, RDRAND, FSGSBASE, INVPCID, HLE, RTM. Generuje kod w

architekturze 16-bitowej, 32-bitowej i 64-bitowej (zarówno AMD64 i EM64T). Używa składni intela.

Page 13: Miłosz Grzegorzewski

FASM – hello world na windowsie

format MZentry .code:startsegment .codestart:

mov ax, .datamov ds, axmov dx, msgmov ah, 9hint 21hmov ah, 4chint 21h

segment .datamsg db 'Hello World on FASM', '$'

Page 14: Miłosz Grzegorzewski

FASM – hello world na windowsie

format MZ ;potrzebne aby program uruchomić w systemie DOS

segment .code ;nasm: .text

segment .data msg db 'Hello World on FASM', '$'

;segment danych;$ - znak zakonczenia zmiennej

Page 15: Miłosz Grzegorzewski

FASM – hello world na windowsie

mov ax, .data mov ds, ax ; zaladowanie ax do segmentu danych

dsmov dx, msg ; zaladowanie msg do dx ( offsetu)mov ah, 9h ;należy wskazać poprawnie gdzie jest

;segment danych i jaki jest offsetu, ;zanim będzie można korzystać z int 21h,

;funkcja 9.

int 21h ;Instrukcja int wywołuje podprogram ;obsługi przerwania o

podanym numerze

Page 16: Miłosz Grzegorzewski

FASM – hello world na windowsie

mov ah, 4chint 21h

;wywołanie funkcji przerwania 21 o numerze 4ch. ;Czyli zakończenie działania programu i oddanie sterowania

;do systemu.

Page 17: Miłosz Grzegorzewski

FASM – hello world na windowsie

Kompilacja:fasm plik_źródłowy.asm plik_wynikowy.exe

Page 18: Miłosz Grzegorzewski

FASM – hello world w systemie linuxformat ELF entry .text:_start segment .data tekst db "Hello World!\n" segment .text _start: xor ebx, ebx mov ecx, tekst mov eax, 4 inc ebx mov edx, 13 int 80H mov eax, 1 xor ebx, ebx int 80H

Page 19: Miłosz Grzegorzewski

FASM – hello world w systemie linux

format ELF;Informuje asembler, że ma utworzyć linuxowy plik wykonywalny

ELF.

segment .data tekst db "Hello World!\n"

;Tworzy wewnątrz obecnie definiowanego segmentu (tj. segmentu .data) ciąg "Hello World" zakończony znakiem nowej

linii.

xor ebx, ebx;zeruje rejestr ebx

Page 20: Miłosz Grzegorzewski

FASM – hello world w systemie linux

mov ecx, tekstmov eax, 4mov ebx, 1

mov edx, 13int 80h

Instrukcja int wywołuje podprogram obsługi przerwania o podanym numerze. Podprogram ów wywołuje odpowiednią funkcję o numerze

podanym w rejestrze eax. Wywołana w tym przypadku funkcja wyświetla w konsoli ciąg znaków, którego adres znajduje w rejestrze ecx

do napotkania znaku o numerze w rejestrze edx. W efekcie na ekranie pojawi się więc napis Hello World!.

Uwaga: należy zaznaczyć, że przerwanie 80h oraz opisana funkcja obsługiwane są przez Unix, przez co kod nie jest przenośny na inne

platformy niż Linux.

Page 21: Miłosz Grzegorzewski

FASM – hello world w systemie linux

mov eax, 1dec ebxint 80h

Wywołuje funkcję przerwania 80 o numerze 1. Odpowiada ona za zakończenie działania

programu i oddanie sterowania do systemu za pomocą kodu wyjścia w rejestrze EBX (instrukcja dec zmniejsza wartość o 1, przez co ebx jest teraz

równy 0).

Page 22: Miłosz Grzegorzewski

FASM – hello world w systemie linux

Kompilacja i utworzenie obiektu wykonywalnego ELF:

fasm prog.asm prog

Page 23: Miłosz Grzegorzewski

GNU Assembler

GNU Assembler (GAS) – darmowy i otwarto źródłowy asembler tworzony przez Projekt GNU.

Jest on domyślnym back-endem GCC, jak i częścią pakietu GNU Binutils.

GAS używa składni AT&T, ale od wersji 2.10 można ją zmienić na składnie Intela dodając na

początku pliku linijkę .intel_syntax.

Page 24: Miłosz Grzegorzewski

GNU Assembler – hello world w systemie Linux

.text ;kod programu

.global _start_start: movl $4, %eax movl $1, %ebx movl $napis, %ecx movl $len, %edx int $0x80

movl $1, %eax movl $0, %ebx int $0x80.datanapis: .string "hello world!\n"len =. - napis

Page 25: Miłosz Grzegorzewski

GNU Asembler – hello world w systemie Linux

movl $4, %eax movl $1, %ebx

movl $napis, %ecx movl $len, %edx

int $0x80

Instrukcja mov (l na końcu to informacja, że zapisujemy dane do 32-bitowego rejestru) przenosi dane do odpowiednich rejestrów - w EAX

znajdzie się numer funkcji systemowej (4 - write), EBX - plik docelowy (1 - standardowe wyjście), w ECX - adres, pod którym znajdują się dane

do wyświetlenia oraz EDX - długość napisu. Instrukcja int powoduje wywołanie przerwania i realizację przez system operacyjny odpowiedniej

czynności - w tym przypadku wypisanie na ekran "Hello world!".

Page 26: Miłosz Grzegorzewski

GNU Asembler – hello world w systemie Linux

movl $1, %eax movl $0, %ebx

int $0x80

Tym razem wywołamy funkcję exit, której argumentem będzie 0. W ten sposób "poprosimy"

system operacyjny o zakończenie pracy programu.

Page 27: Miłosz Grzegorzewski

GNU Asembler – hello world w systemie Linux

len = . - napis

Jest to zmienna, która zawiera długość napisu. Kropka oznacza "aktualny adres" w pamięci (w naszym przypadku koniec napisu), a "napis" -

adres etykiety, pod którą zawarto początek napisu. Różnica koniec - początek daje długość napisu, która jest niezbędna, aby program wypisał na ekranie dokładnie tyle znaków, ile liczy sobie

napis.

Page 28: Miłosz Grzegorzewski

GNU Asembler – hello world w systemie Linux

Kompilacja:as hello.s -o hello.o

Tak otrzymany kod wynikowy, musimy poddać działaniu linkera ld:ld hello.o -o hello

Uruchomienie:./hello

Page 29: Miłosz Grzegorzewski

GNU Asembler – hello world w systemie Windows

Analogiczny program, który kompiluje się pod systemem DOS(będąc emulowanym pod Windowsem) mógłby wyglądać np. tak:

.data napis: .string "Hello World!\n$" .text .globl _start _start: movw $napis, %dx movb $9, %ah int $0x21 movw $0x4C00, %ax int $0x21

Page 30: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

1. Odnoszenie się do rejestrów

AT&T: % eaxIntel: eax

Page 31: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

2. Kolejność zapisu źródło/cel – zapisanie wartości rejestru eax do rejestru ebx

AT&T: movl %eax, %ebx ;UNIX standardIntel: mov ebx, eax

Page 32: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

3. Załadowanie do rejestru wartości stałej/zmiennej - "$"

AT&T: movl $0xd00d, %ebxIntel: mov ebx, d00dh

Page 33: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

4. Określanie rozmiaru operatora – składnia AT&T wymaga podania rozmiaru operatora (byte,word,longword), w przeciwnym razie będzie „zgadywać” czego lepiej unikać.

AT&T: movw %ax, %bxIntel: mov bx, ax

Page 34: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

5. Intel posiada równoważne formy określania rozmiaru operatora takie jak: byte ptr, word ptr i dword ptr, jednak używane tylko w sytuacji odwoływania się do pamięci.

Podstawowy format adresowania 32 bitowego

AT&T: immed32(basepointer,indexpointer,indexscale)Intel: [basepointer + indexpointer*indexscale + immed32]

Page 35: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

6. Formy adresowania

Page 36: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

a) adresowanie poszczególnych zmiennych statycznych

AT&T: _boogaIntel: [_booga]

„_” jest sposobem dostępu do zmiennych statycznych globalnych.

Page 37: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

b) adresowanie pośrednie

AT&T: (%eax)Intel: [eax]

Page 38: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

c) Addressing a variable offset by a value in a register

AT&T: _variable(%eax)Intel: [eax + _variable]

Page 39: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

d) Addressing a value in an array of integers (scaling up by 4)

AT&T: _array(,%eax,4)Intel: [eax*4 + array]

Page 40: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

e) Adresowanie pooprzez przesunięcia o natychmiastową wartośc:

AT&T: 1(%eax) Intel: [eax + 1]

Page 41: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

f) Można również wykonać proste działanie matemtyczne na zmiennej dynamicznej:

AT&T: _struct_pointer+8Prawdopodobnie można to również wykonać w składni intelaIntel: [_struct_pointer]+8

Page 42: Miłosz Grzegorzewski

Assembler - różnice w składni Intel i AT&T

g) Addressing a particular char in an array of 8-character records:eax holds the number of the record desired. ebx has the wanted

char's offset within the record.

AT&T: _array(%ebx,%eax,8)Intel: [ebx + eax*8 + _array]

Page 43: Miłosz Grzegorzewski

Dziękuje za uwagę :)