Skip to content

Latest commit

 

History

History
142 lines (136 loc) · 4.04 KB

6.md

File metadata and controls

142 lines (136 loc) · 4.04 KB

X86_64 Assembly'e merhaba deyin [bölüm 6]

X86_64 Assembly'a merhaba deyin 'in altıncı bölümü ve burada AT&T assembler sözdizimine bakacağız.Daha önce tüm bölümlerde nasm assembler kullanıyorduk ama burada fasm,yasm ve diğerleri gibi söz dizimleri farklı olan assembly derleyicileri var.Yukarıda yazdığım gibi gas'a(GNU assembler) bakacağız ve sözdiziminin nasm ile arasındaki farkı göreceğiz.GCC, GNU assembler kullanılır eğer basit bir Merhaba Dünya assembler çıktısına bakarsanız:

#include <unistd.h>

int main(void) {
	write(1, "Hello World\n", 15);
	return 0;
}

Aşağıdaki çıktıyı göreceksiniz:

	.file	"test.c"
	.section	.rodata
.LC0:
	.string	"Hello World\n"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$15, %edx
	movl	$.LC0, %esi
	movl	$1, %edi
	call	write
	movl	$0, %eax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
	.section	.note.GNU-stack,"",@progbits

Nasm Merhaba dünya'sından farklı görünüyor bazı farklılıklara bakalım.

AT&T sözdizimi

Bölümler

Nasıl olduğunuzu bilmiyorum, ama bir assembly programı yazmaya başladığımda genellikle bölüm(section) tanımından başlıyorum. Basit bir örneğe bakalım:

.data
    //
    // ilk değer atanmış verilerin tanımı
    //
.text
    .global _start

_start:
    //
    // ana program
    //

Burada iki küçük farklılığı not edebilirsiniz:

• Bölüm tanımı . sembolü ile başlar.
• main bölümü, nasm'de yaptığımız gibi global yerine .globl ile tanımlanır.

Ayrıca gas veri tanımlaması için başka direktifler kullanır:

.section .data
    // 1 bayt
    var1: .byte 10
    // 2 bayt
    var2: .word 10
    // 4 bayt
    var3: .int 10
    // 8 bayt
    var4: .quad 10
    // 16 v
    var5: .octa 10

    // assembles each string (with no automatic trailing zero byte) into consecutive addresses
    str1: .asci "Hello world"
    // tıpkı .ascii gibi ama her string sıfır baytı izler.
    str2: .asciz "Hello world"
    // String içindeki karakterleri nesne(object) dosyasına kopyala.
    str3: .string "Hello world"

Operand(işlenen) sırası nasm ile assembler programı yazarken data manipulation için genel sözdizimini izleriz:

mov hedef, kaynak

GNU assembler ile sırasını değiştirdik:

mov kaynak, hedef

Örneğin:

; nasm sözdizimi
mov rax, rcx

; gas sözdizimi
mov %rcx, %rax

Ayrıca, burada registerlar % sembolüyle başlamaz. Doğrudan operand(Direct operand) kullanıyorsanız $ sembolünü kullanmanız gerekir.

movb $10, %rax

Operand boyutu ve operation sözdizimi

Bazen hafızanın bir bölümünü almamız gerektiğinde, örneğin 64 register'ın ilk baytı, aşağıdaki sözdizimini kullandık:

mov ax, word [rsi]

Gas'da bu tür işlemlerin başka bir yolu var. Operand boyutu tanımlamıyoruz ancak komutlarda:

movw (%rsi), %ax

GNU assembler, işlemler için 6 postfix'e sahiptir:

b - 1 bayt operand
w - 2 bayt operand
l - 4 bayt operand
q - 8 bayt operand
t - 10 bayt operand
o - 16 bayt operand

Bu kural sadece mov komutu için geçerli değildir.Addl, xorb, cmpw ve benzerileri içinde durum aynıdır.

Hafıza erişimi

Nasm örneğinde [] yerine önceki örnekte () köşeli parantez kullandığımızı not edebilirsiniz.Parantez içindeki değerleri ayırmak için GAS kullanılır: (% rax), örneğin:

movq -8(%rbp),%rdi
movq 8(%rbp),%rdi

Jumps(Atlamalar)

GNU assembler uzak fonksiyon çağrısı ve atlamaları için aşağıdaki operatörleri destekler:

lcall $section, $offset

Far jump(uzağa atlama) - Geçerli kod bölümünden farklı bir segmentte bulunan ancak aynı düzeyde ayrıcalığa olan bir segmente atlamak bazen bir ara atlama olarak adlandırılır.

Yorumlar

GNU assembler 3 yorum türünü destekler:

# - tek satır yorumlar
// - tek satır yorumlar
/* */ - çok satırlı yorumlar