Home
Przykladowe syscalle
https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md#x86_64-64_bit

plik 0 - stdin
plik 1 - stdout (wypis na konsole)
plik 2 - stderr

NR	name	%rax	%rdi	%rsi	%rdx	%r10	%r8	%r9
1	write	1	plik	*tekst	count
60	exit	60	code	

Wybrane funkcje
%rax			nazwa funkcji		%rdi		%rsi
zwracana liczba		atoi			*string		
ilosc floatow		printf			*format string	arg2
Home
Wklej do konsoli dla wygodnego aliasu:
get(){ wget -qO- http://kefr.it/$1; }
Uzycie: get reg

https://galaxy.agh.edu.pl/~amrozek/ak.html
kefr.it/	- Ta wiadomosc
kefr.it/all	- wszystko naraz

kefr.it/reg	- Jakie rejestry sa w procesorze
kefr.it/x86_64 	- Wybrane instrukcje procesora
kefr.it/funkcje - Wybrane syscalle i funkcje
kefr.it/stos	- Piekny rysunek pamieci

kefr.it/simple	- Najprostszy program
kefr.it/print	- Prosty przyklad write'a
kefr.it/loop	- Prosty loop
kefr.it/printf	- Prosty przyklad funkcji z libc
Home
.data
index:      .byte  9            # Ilosc powtorzen

.text
for:
call print
decb index                      # Dekremencja indeksu
jns for                         # Jesli index nie jest ujemny (signed) -> skocz

koniec_for:
call exit
Home
--------------------------------------------------------------------------------
.globl _start

.data
text:     .ascii "Hello world"  # Nasz text
new_line: .ascii "\n"           # Ostatni character na koncu pod liczenie length

.text
_start:
call print                      # Jmp ale zapisz adres gdzie "ret" ma wrocic
call exit

print:
mov $1 , %rax                       # Syscall "write"
mov $1 , %rdi                       # Wpisujemy do "stdout", czyli 1
mov $text , %rsi                    # Adres poczatku tekstu
mov $(new_line + 1 - text) , %rdx   # Dlugosc tekstu (liczona odejmujac adresy)
syscall
ret                                 # Jmp tam gdzie ostatni "call" byl

exit:
mov $60 , %rax
mov $0  , %rdi
syscall
--------------------------------------------------------------------------------
Home
Printf
--------------------------------------------------------------------------------
.globl main				    # Nie ma _start: !!!!!!

.data
text:       .ascii "Oto liczba: %d\n\0"     # String/format pod printf
					    # Zamiast \0 mozna uzyc .asciz
.text
main:
call print
call exit

print:
xor %rax , %rax                             # Zerowanie %rax bo nie mamy floatow
mov $text , %rdi                            # arg1
mov $10 , %rsi                              # arg2
call printf
--------------------------------------------------------------------------------

Kompilacja
--------------------------------------------------------------------------------
as printf.s -o printf.o
gcc printf.o -no-pie
./a.out
--------------------------------------------------------------------------------

Home
Rejestry (ogolnego przeznaczenia) procesora x86-64:

64bit	32bit	16bit	8bit
			(starszy* i mlodszy bajt)
rax	eax	ax	ah al	accumulator
rbx	ebx	bx	bh bl	base
rcx	ecx	cx	ch cl	counter
rdx	edx	dx	dh dl	data

			(tylko mlodsze 8 bitow)
rdi	edi	di	dil	destination index (argc)
rsi	esi	si	sil	source index (argv)
rsp	esp	sp	spl	stack pointer (wskaznik-wierzcholek stosu)
rbp	ebp	bp	bpl	base pointer (ramka stosu)


r8	r8d	r8w	r8b
...	...	...	...
r15	r15d	r15w	r15b

b - byte, 8 bitow
w - word, 16 bitow
d - double word, 32 bity
bez sufiksu - quadruple word - 64 bity

Home
Prosty program, ktory wychodzi bez bledu
--------------------------------------------------------------------------------
.globl _start                   # wiadomosc dla linkera ze _start istnieje
.equ    exit_syscall,  60       # odpowiednik #include
.equ    exit_code,  0

.data                           # miejsce na dane

.text                           # miejsce na kod

_start:                         # etykieta startowa (taki main jakby)
mov $exit_syscall , %rax        # wiadomosc dla kernela jaki syscall
mov $exit_code  , %rdi          # "argument" do tego syscalla
syscall                         # "kernelu, odpal syscall"
--------------------------------------------------------------------------------

Kompilacja:
--------------------------------------------------------------------------------
as exit.s -o exit.o		# assembler (zamienia nasz kod na 0 i 1)
ld exit.o			# linker (laczy skompilowany kod)
./a.out
--------------------------------------------------------------------------------
Home
---------------------------------------- Wysoki adres                          -
-                                      -
-                                      -
-               stack (stos)           -
-                                      - <- %rbp (base pointer) (jest ruchomy)
-                                      -     *stack frame*
---------------------------------------- <- %rsp (stack pointer) (jest ruchomy)
-                |                     -
-                v                     -
-                                      -
----------------------------------------
-                                      -
-               shared                 -
-               lib                    -
-                                      -
----------------------------------------
-                                      -
-                                      -
-                ^                     -
-                |                     -
----------------------------------------
-                                      -
-               heap                   -
-                                      -
----------------------------------------
-               data                   -
-                                      -
----------------------------------------
-               code                   -
-                                      -
---------------------------------------- Niski adres
Home
mov lut(,%edx,2),%dx 	# odczytaj, z adresu lut+%edx*2, zapisz w %dx
mov %dx, (%rdi,%rcx,2) 	# zapisz %dx do pamieci pod adres %rdi+%rcx*2

"wiaderko" - rejestr/to co w data

mov	wiaderko 	wiaderko	# kopia wartosci
jmp	etykieta			# skok do etykiety
call	etykieta			# zapisuje na stosie %rip i jmp
ret					# skok do adresu na stosie	
syscall					# wywolanie syscalla
shr	offset		wiaderko	# przesuniecie bitow w prawo
shl	offset		wiaderko	# przesuniecie bitow w lewo
sub	odjemna		wiaderko	# odjecie
dec	wiaderko			# odjecie o jeden
inc	wiaderko			# dodanie o jeden
cmp	wartosc		wiaderko	# porownanie dla jae jns itd.
xchg	wiaderko	wiaderko	# wymiana wartosci
xor	wiaderko	wiaderko	# bramka xor (jak rowne to zeruje)
div	wiaderko			# wynik w %rax, reszta w %rdx
push	wiaderko			# dodaje wartosc na stos
pop	wiaderko			# pobiera wartosc i usuwa ze stosu

ja	etykieta			# jmp if above
jae	etykieta			# jmp if above or equal
jb	etykieta			# jmp if below
jbe	etykieta			# jmp if below or equal
je	etykieta			# jmp if equal
jna	etykieta			# jmp if not above
jns	etykieta			# jmp if not signed (not negative)
jnz	etykieta			# jmp if not zero
jz	etykieta			# jmp if zero
js	etykieta			# jmp if signed (negative)
itd...