Język Asembler

W Linux-ie używana jest inna składnia języka Assembler, tak zawana składnia AT&T, niż w DOS-ie, gdzie używana jest składnia Intel-a. Różnice występują w niektórych elementach języka.

Prefiksy

W AT&T nazwy rejestrów są poprzedzana znakiem %, natomiast liczby znakiem $.

Kierunek operacji

W standardzie Intel-a to parametr, który jest parametrem źródłowym znajduje się po prawej stronie. W AT&T jest odwrotnie.

Pamięć

Oparatory odnoszące się do pamięci są też różne. Zamiast "[]" używamy "()".

Sufiksy mnemoników

W standardzie AT&T mnemoniki są kończone literą oznaczającą wielkość parametrów.


Przykłady:

mov eax, 1 movl $1, %eax
mov ebx, 0ffh movl $0xff, %ebx
int 80h int $0x80
mov eax, [ebx+5] movl 5(%ebx), %eax
add eax,[ebx+ecx*2h] (%ebx,%ecx,0x2),%eax
sub eax,[ebx+ecx*4h-20h] subl -0x20(%ebx,%ecx,0x4),%eax
mov ax,bxmovw %bx,%ax

Przerwania systemowe

W Linux-ie przerwaniem systemowym jest przerwanie 0x80h. Jest to odpowiednik przerwania 21h w DOS-ie. Numer przerwania zgodny z plikiem sys/syscall.h umieszany jest w rejestrze %eax, tam też jest zwracana wartość funkcji. Parametry powinny się znaleźć w kolejnych rejestrach.

Asemblacja inline w gcc

Asemblacje inline umozliwia makro __asm__, lub asm, przyjmujace jako parametr string, będący kodem assemblera. Na przykład:

__asm__("movl %esp,%eax");

Można też korzystać z makra postaci __asm__("polecenia":input:output:modify).

Użyteczne jest też polecenie __volatile__ chroniące instrukcje assemblera przed zmianami optymalizacyjnymi przez kompilator.

volatile__ __asm__("
test %0,%0
test %1,%1
test %2,%2"
: /* no outputs */
: "a"((long)eax), "b"((short)bx), "c"((char)cl)
);

Kompilacja

Istnieją dwie metody skompilowania kodu assemblera.
  • Listing 1
.data
hw:
	.string "hello world\n"
.text
.globl main
main:
	movl	$SYS_write,%eax
	movl	$1,%ebx
	movl	$hw,%ecx
	movl	$12,%edx
	int	$0x80
	movl	$SYS_exit,%eax
	xorl	%ebx,%ebx
	int	$0x80
	ret
$ gcc -o write write.s
$ wc -c ./write
   4790 ./write
$ strip ./write
$ wc -c ./write
   2556 ./write
  • Listing 2
.data
hw:
	.string "hello world\n"
.text
.globl _start
_start:
	movl	$SYS_write,%eax
	movl	$1,%ebx
	movl	$hw,%ecx
	movl	$12,%edx
	int	$0x80
	movl	$SYS_exit,%eax
	xorl	%ebx,%ebx
	int	$0x80

$ gcc -c write.s
$ ld -s -o write write.o
$ wc -c ./write
    408 ./write


Powrót