Nasm etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Nasm etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Bit Düzeyinde İşlemler Yapan Makine Komutları

07:10 ,


Sembolik makine dillerinde bit düzeyinde işlemlere sıkça ihtiyaç duyulmaktadır. Bu nedenle bit düzeyinde işlem yapan komutları bilmek gerekmektedir. Şimdi temel bit işlemlerini yapan makine komutları sırasıyla görelim.

AND ve OR Komutları


AND ve OR komutları iki tamsayı değerin karşılıklı bitlerini AND ve OR işlemlerine sokmaktadır. Örneğin:

AND eax, ebx
OR eax, [ebx + ecx]
AND eax, 1

⦁ Komut sonucunda her zaman OF ve CF bayrakları reset’lenir.
⦁ AF bayrağının durumu tanımsızdır (undefined).
⦁ İşlemden SF, ZF, PF bayrakları etkilenir.

AND işleminin operand'ı etkilemeyen yalnızca bayrakları etkileyen TEST isimli bir komutta bulunmaktadır. AND ile TEST arasındaki ilişki SUB ile CMP arasındaki ilişkiye benzetilebilir. TEST işlemi AND işlemi yapar fakat bu işlemden yalnızca bayraklar etkilenir. Pekiyi TEST işleminin ne faydası vardır? Bir değeri kendisiyle AND işlemine soktuğumuzda onunla aynı değeri elde ederiz. Fakat bu işlemden bayraklar etkileneceği için artık koşullu jump işlemi yapılabilir. Örneğin EAX’teki değer negatifse jump etmek isteyelim. Henüz bir işlem yapmadığımıza göre bayraklara bakamayız. Bayrakları etkileyecek bir işleme ihtiyacımız vardır. Bu AND işlemi ya da TEST işlemi olabilir:

TEST EAX, EAX
JS EXIT

Bu işlemle EAX’teki değer negatif ise jump yapılmaktadır. Benzer biçimde:

TEST EAX, EAX
JNZ EXIT

Burada da EAX’teki değer sıfır değilse jump yapılmıştır.


XOR Komutu


XOR komutu iki değerin karşılıklı bitlerini exclusive or işlemine sokar. Exclusive or işlemi iki bit aynıyse 0, farklıysa 1 değerini veren bir işlemdir. Exclusive or işlemi geri dönüşümlüdür. Bu nedenle şifreleme gibi işlemlerde tercih edilir. Aynı değeri kendisiyle exclusive or işlemine sokarsak sıfır elde ederiz. Bu nedenle assembly programcıları bir yazmacı sıfırlamak için bu komutu sık kullanmaktadır:

XOR EAX, EAX

Aynı işlem MOV ile yapılırsa komut uzamaktadır:

MOV EAX, 0

Eskiden XOR işlemi SUB işleminden daha hızlıydı. Ancak artık bunlar aynı hızdadır:

SUB EAX, EAX

⦁ Komut sonucunda her zaman OF ve CF bayrakları reset’lenir.
⦁ AF bayrağının durumu tanımsızdır (undefined).
⦁ İşlemden SF, ZF, PF bayrakları etkilenir.

NOT Komutu

Tek operandlı bir komuttur. Girilen sayının değilini alır. Aşağıdaki örnekte olduğu gibi;

param equ                         0101 0011
NOT param -> Operand1:    1010 1100
çalışır.

Öteleme (Shift) Komutları

07:11 ,


C/C++ dillerinde "<<" ve ">>" operatörleri aslında işlemcinin sola ve sağa öteleme komutlarına karşılık gelmektedir. Öteleme işlemleri  Intel işlemcilerinde SAL, SAR, SHL ve SHR makine komutları ile yapılmaktadır.

  • SAL (Shift Arithmetic Left) ve SAR (Shift Arithmetic Right) komutlarına aritmetik öteleme komutları
  • SHL (Shift Logical Left), SHR (Shift Logical Right) komutlarına da mantıksal öteleme komutları denilmektedir.

SAL ve SHL komutları arasında farklılık yoktur. SAR ile SHR komutları arasında ise küçük bir farklılık vardır. Diğer yüksek seviyeli dillerden de bilindiği gibi sola bir kez ötelemede bütün bitler bir sola kaydırılır ve sağdan sıfır ile besleme yapılır. Sağa bir kez ötelemede ise bütün bitler bir sağa kaydırılır ancak en soldan 0 ile mi 1 ile mi besleme yapılacağı SAR ve SHR komutlarında değişmektedir. SAR komutunda besleme işaret bitiyle, SHR komutunda ise her zaman 0 ile yapılmaktadır. SAL ve SHL komutları arasında bunun dışında hiçbir fark yoktur. Mantıksal bütünlük oluşturmak için sanki iki farklı komut varmış gibi isimlendirme yapılmıştır. (Yani aslında SAL ve SHL iki ayrı makine komutu değil aynı komutun iki farklı ismidir.) 1' den fazla kez ötelemede aynı işlemler birden fazla yapılmaktadır. Öteleme komutlarında ötelenecek operand yazmaç ya da bellek olabilir. Bir kez öteleme için 2 byte’lık bir komut versiyonu (opcode) bulundurulmuştur. Birden fazla öteleme yapılmak isteniyorsa öteleme sayısı ya sabit olarak verilmek zorundadır ya da CL yazmacına yerleştirilmek zorundadır. Öteleme miktarının sabit olarak verilmesi durumunda ise komut uzunluğu 3 byte olur. Eğer komut uzunluğu CL yazmacına yerleştirilirse bu durumda komut uzunluğu yine 2 byte’tır. Örneğin bazı geçerli öteleme komutları şöyle olabilir:

sal  eax, 1      ; komut uzunluğu 2 byte
shl  dword [ebx], 5    ; komut uzunluğu 3 byte 
sar  byte [ebx + ecx], cl   ; komut uzunluğu 2 byte
Aşağıdaki komutlar ise geçersizdir:
sal eax, bl ; geçersiz!
sal ebx, ecx ; geçersiz!

Komutların bayrakları etkilemesi şöyle olmaktadır: Her zaman kaybedilen bit CF bayrağına yerleştirilir. Yani örneğin biz sola bir kez öteleme yaptığımızda en soldaki bit CF bayrağına yerleşecektir. Sağa bir kez öteleme yaptığımızda da en sağdaki bir CF bayrağına yerleşir. Birden fazla öteleme yapıldığında son ötelemede kaybedilen bit CF’de kalır. SHL ve SHR komutlarında öteleme sayısı ötelenmek istenen değerin bit uzunluğunun bir eksiğini aşıyorsa bu durumda CF bayrağı tanımsız durumdadır. OF bayrağı yalnızca 1 kez ötelemede etkili olur. Birden fazla kez ötelemede OF de tanımsız durumdadır. Bir kez ötelemede OF bayrağı bize sayıda işaretli taşma olup olmadığını bildirmektedir. Ayrıca SF, ZF ve PF bayrakları normal biçimde işlemden etkilenirler. Sıfır kere öteleme geçerlidir. Ancak bu durumda işlemden bayraklar etkilenmez.

Sola öteleme bilindiği gibi iki ile çarpma anlamına, sağa öteleme ise iki ile bölme anlamına gelmektedir. İşaretli sayıların sağa ötelenmesi için SAR komutu işaretsiz sayıların sağa ötelenmesi için SHR komutu kullanılmaktadır. İşaretli ya da işaretsiz sola öteleme için aslında yukarıda da belirtildiği gibi tek bir komut vardır. Bu komuta SAL ve SHL isimleri verilmiştir.

Mantıksal sağa ötelemede en soldan beslemenin 0 ile artimetik sağa ötelemede ise 1 ile yapıldığını anımsayınız. Örneğin AL yazmacında aşağıdaki değerin bulunduğunu düşünelim:

AL: 1011 0111

Şimdi AL yazmacındaki değeri SAR AL, 1 ile aritmetik olarak bir kez sağa öteleyelim. AL’deki değer şu hale gelecektir.

AL: 1101 1011

Oysa AL’ye SHR AL, 1 komutuyla mantıksal sağa öteleme uygulasaydık AL’deki değer şu hale gelecekti:

AL: 0101 1011

Bildiğiniz gibi sağa öteleme sayıyı tamsayısal olarak (yani nokta oluşmayacak biçimde) ikiye bölme anlamına gelir. Fakat aritmetik sağa ötelemede eğer ötelenecek değer negatifse sonuç azalacak biçimde (yani eksi sonsuza doğru) tamsayı olarak elde edileceğine dikkat ediniz. Yani örneğin biz -3 değerini bir kez sağa aritmetik ötelemek isteyelim:

1111 1101 -3

Sağa bir kez artimektik ötelendiğinde sayının -2 olduğuna dikkat ediniz:

1111 1110 -2

Örnek çalışmalar;
 

Koşullu Jump Komutları

07:20 , ,
Jump komutları sembolik makine dillerinin mutlaka bilinmesi gereken komutlarındandır. Bazı işlemci ailelerinde bu komutlara branch (dallanma) komutları denilmektedir. Jump komutları olmadan yüksek seviyeli dillerdeki if, switch, while for gibi deyimler gerçekleştirilemez. Jump komutları 
  • koşulsuz (unconditional) 
  • koşullu (conditional) olmak üzere ikiye ayrılmaktadır. 
Koşulsuz jump komutları C’deki goto deyimi gibidir. Koşulsuz olarak EIP yazmacını belli bir değere çeker. Koşulsuz jump komutlarının doğrudan (direct) ve dolaylı (indirect) biçimleri de vardır. Koşulsuz jump komutları pek çok işlemcide olduğu gibi göreli uzaklık değerini operand olarak alır. Doğrudan koşulsuz jump komutlarının son byte’larından sonraki ilk byte göreli uzaklık için sıfır orijini belirtir. Negatif uzaklık "yukarıya", pozitif uzaklık "aşağıya" jump yapılacağı anlamına gelmektedir.

Koşullu Jump Komutları

Koşullu jump komutları bayraklara bakarak jump işlemi yapmaktadır. Intel’deki bütün koşullu jump komutları doğrudandır ve "göreli uzunluk" değerini operand olarak alırlar. Bayrakların uygun karşılaştırma sonuçlarını içermesi SUB ya da CMP komutlarıyla sağlanmaktadır. Bu nedenle önce bayrakların karşılaştırma için set ya da reset edilmesi gerekir. Yani koşullu jump komutları tipik olarak SUB ya da CMP komutlarından sonra uygulanmaktadır. Zaten onların isimlendirmeleri de SUB ya da CMP komutlarından sonra kullanılacağı fikriyle yapılmıştır. Intel’de çok fazla koşullu jump komutu varmış gibi görülse de aslında bazı komutlar diğerleriyle aynı işlemi yaparlar. Yani bu komutlar aynı makine kodunun farklı isimleridirler. Örneğin JA ile JNBE aslında aynı komutlardır. Bunlar tek bir komutun iki farklı isimleridir desek yanlış olmaz. Koşullu jump komutlarının isimlendirilmeleri SUB ya da CMP komutlarının birinci operandına göre yapılmıştır. Örneğin:

cmp eax, ebx
jb REPEAT

Burada jb (jump below) eax’teki değer ebx’teki değerden küçükse anlamına gelmektedir. İsimlendirmede A (Above) ve B (Below) işaretsiz tamsayılar için G (Greater) ve L (Less) de işaretli sayılar için kullanılmaktadır. Eşitlik E (Equal) ya da Z (Zero flag set) ile ifade edilebilmektedir. Koşullu jump komutlarında eğer koşul sağlanmışsa jump işlemi yapılır. Eğer koşul sağlanmamışsa sonraki komuttan devam edilir. Aşağıda tüm jump komutlarının listesi verilmiştir:





Sembolik makine dilinde döngüler ve if deyimleri koşullu ve koşulsuz jump komutlarının kullanılmasıyla gerçekleştirilir. Örneğin aşağıdaki gibi bir C kodunun sembolik makine dili karşılığını yazmak isteyelim:

int g_x = 0;
/* ... */
while (g_x < 10) {
printf(“AhmetUlucay\n”);
++g_x;
}

Böyle bir while döngüsü aşağıdaki gibi oluşturulabilir:


Döngüdeki en önemli nokta şurasıdır:

cmp dword [g_x], 10
jge EXIT

Burada g_x ile 10 değeri karşılaştırılmıştır. Eğer g_x 10'dan büyükse ya da 10'a eşitse while koşulu sağlanmadığı için döngüden çıkılmıştır. Eğer bu koşul sağlanmıyorsa akış aşağıdan devam eder. Orada da mesaj ekrana yazdırılmıştır. Dönünün devamının sağlanması için yukarıya jump yapıldığına dikkat ediniz:

; ...
inc dword [g_x]
jmp REPEAT

Şimdi de aşağıdaki while döngüsünü sembolik makine dilinde yazmaya çalışalım:

unsigned g_x = 10;
while (g_x != 0) {
/* ... */
--g_x;
}

Kodun eşdeğer assembly karşılığı şöyle olabilir:

REPEAT:
cmp dword [g_x], 0
je EXIT
;  ...
dec dword [g_x]
jmp REPEAT
EXIT:
; ...

Tabii bu döngüyü şöyle de oluşturabilirdik:

cmp dword [g_x], 0
je EXIT
REPEAT:
; ...
dec dword [g_x]
jnz REPEAT
EXIT:
; ...

Burada dec komutuyla g_x değeri sıfıra düştüğünde ZF bayrağı set edileceğine dikkat ediniz. do-while döngüleri de benzer biçimde yapılabilir. Örneğin:

unsigned g_x = 10;
do {
/* ... */
--g_x;
} while (g_x != 0);

İşlemi sembolik makine dilinde şöyle yapılabilir:

REPEAT:
; ...
dec dword [g_x]
jnz REPEAT

for döngüleri de benzer biçimde sembolik makine dilinde oluşturulabilir. (Örneklerimizde stack görmediğimiz için hep global değişkenleri kullanıyoruz). Örneğin:

int g_i;
/* ... */
for (g_i = 0; g_i < 10; ++g_i) {
/* ... */
}

Bu işlemin sembolik makine dili karşılığı şöyle oluşturulabilir:

MOV dword [g_i], 0
@2:
cmp dword [g_i], 10
jge @1
; ...
inc dword[g_i]
jmp @2
@1:
; ...

Notlar: jmp işlemlerinde etiket kullanırken isim uydurmak zordur. Sembolik makine dilinde @ karakteri geçerli bir isimlendirme karakteridir. Pek çok C derleyicisi programın sembolik makine dili karşılığını oluştururken bu biçimdeki fabrikasyon etiketleri kullanmaktadır.

if deyimleri de yine koşullu ve koşulsuz jump komutlarıyla gerçekleştirilir. Örneğin yalnızca doğruysa kısmı olan bir if deyimi düşünelim:

if (g_i > 100) {
/* ... */
}
/* ... */

Bu işlem aşağıdaki gibi sembolik sembolik makine dilinde ifade edilebilir:

cmp dword [g_i], 100
jle @1
; doğruysa kısmı
@1:
; if deyimin dışı

Şimdi de else kısmı olan bir if deyimini sembolik makine dili ile ifade etmeye çalışalım:

if (g_i > 10) {
/* ... */
}
else {
/* ... */
}

Bu işlemin eşdeğer sembolik makine dili karşılığı şöyle olabilir:

cmp dword [g_i], 10
jle @1
; if’in doğruysa kısmı
jmp @2
@1:
; if’in yanlışsa kısmı
@2:

Şimdi de else-if örneği üzerinde duralım:

int g_a;
if (g_a > 0) {
/* .... */
}
else if (g_a < 0) {
/* ... */
}
else {
/* ... */
}

Bu işlemin sembolik makine dili karşılığı şöyle oluşturulabilir:

cmp dword [g_a], 0
jle @1
; g_a > büyükse sıfır
jmp @3
@1:
cmp dword [g_a], 0
jge @2
; g_a < 0
jmp @3
@2:
; g_a == 0
@3:

Fonksiyona yazmaç (register) yoluyla parametre aktarımı

05:07 ,
Eğer tüm işlemlerini assembly dili ile kendiniz yazacaksanız bu durumda genel amaçlı tüm register'ları fonksiyonlarınıza parametre aktarma için kullanabilirsiniz. Aşağıdaki örnekte eax, ebx, ecx register'ları bu amaçlarla kullanılmıştır.


AddProc fonksiyonu işini yaparken parametrelerin nerede olduğunu bildiği için o yazmaçlardan değerleri alarak işlemini gerçekleştirmiş ve ret komutu ile geri dönülmüştür. Compile işlemi nasm ile link işlemi gcc ile gerçekleştirilmiş ve kod çalıştırıldığında sorunsuz bir şekilde çalıştığı görülecektir. Tabii ki bu şekilde kod yazma ne portable ne de başkası tarafından kullanılabilir bir kod örneğidir. ABI kavramıda zaten bu tür durumlar için ortak bir standart oluşturmak için belirlenmiştir.


32 Bit Windows Sistemler için "Hello World" Assembly Programı


Tamamen sembolik makine diliyle yazılmış ekrana "Hello World" yazısını çıkartan temel assembly  programı Windows'ta şöyle yazılabilir:


  • Aşağıdaki resimde görüleceği gibi ilk adım olan yazılan kodu 1 numaralı komutta olduğu gibi nasm ile derlenebilir:


Buradan ürün olarak HelloWorld.obj dosyası elde edilecektir. Komuttaki –f win32 seçeneği amaç kodun 32 bit Windows sistemleri için COFF formatında olmasını sağlar.

  • Yukarıdaki resimde görüleceği gibi 2 numaralı komutta olduğu gibi Microsoft’un link.exe programı ile link edilmelidir.

Komuttaki /entry:start seçeneği programın başlangıç noktasını belirlemek için kullanılır. HelloWorld.asm programının başlangıç noktası _start etiketinin bulunduğu yerdedir. Windows uygulamaları “GUI” ve “Console” olmak üzere ikiye ayrılmaktadır. Console uygulamalarında işletim sistemi programı yüklendiğinde bir console ekranını kendisi oluşturmaktadır. Console uygulaması için /subsystem:console seçeneği kullanılmalıdır. Link edilecek dosya HelloWorld.obj dosyasıdır. "Hello World" programında kernel32.dll içerisindeki çeşitli API fonksiyonları (sistem fonksiyonları) kullanılmıştır. Bu nedenle link aşamasına "kernel32.lib" isimli import kütüphanesinin dahil edilmesi gerekmektedir. Bu programda üç API fonksiyonu çağrılmıştır. Önce GetStdHandle API fonksiyonuyla (kodun içerisinde 1 numaralı kısım) console ekranının handle değeri elde edilmiş, sonra WriteFile API fonksiyonu (kodun içerisinde 2 numaralı kısım) ile oraya yazma yapılmıştır. Prosesin sonlanması için ExitProcess API fonksiyonuyla (kodun içerisinde 3 numaralı kısım) gerçekleştirilmiştir. C’nin standart exit fonksiyonu da zaten ExitProcess API fonksiyonu çağırır. Ve link işleminden sonra üretilen exe dosya çalıştırıldığında aşağıdaki gibi başarıyla çalıştığı görülebilir.





Assembly ile Sistem Fonksiyonu Çağırma [Linux]

06:50 , , , ,


Assembly programı içinden Linux sistem fonksiyonları çağrılırken uyulması gereken standart işlemler vardır. Linux System Call Table 'da görülebileceği gibi hangi register'ları set etmemiz gerektiği, parametreleri hangi register aracılığıyla göndermemiz gerektiği bilinmesi gerekmektedir. 80h kesmesinden sonra hangi fonksiyonun çağrılacağı bu registerlardaki değerler üzerinden belirlenmektedir.


Aşağıdaki örnekte ekrana "Hello world" yazan programı yazacağız:


Yukarıda görüldüğü gibi ;

  • eax'e hangi sistem fonksiyonu yazılacaksa onun numarası 
  • ebx'e birinci parametre olan file descripter değeri -stdout için 1- 
  • ecx'e yazılacak string'in adresi
  • edx'e ise  kaç karakter yazılacak ise onun uzunluğu girilmelidir.



Gerekli çağırma parametreleri girildikten sonra 80h kesmesiyle kernel mod'a geçiş yapar ve sistem fonksiyonları çağrılır.



Yukarıdaki kod derlenip,link edilip çalıştırıldığında ekrana Hello World yazısı çıkacaktır. Ekrana yazma işini sys_write sistem fonksiyonu ile stdout'a yazarak gerçekleştirilmiştir.

Assembly içinden C Fonksiyonu Çağırma [Linux]

03:23 , , , ,


Linux'te assembly içinden C fonksiyonu çağrılacak ise yapılması gereken temel işlemler aşağıdaki örnekte anlatıldığı gibidir:

  • Çağrılacak fonksiyon .text alanında extern bildirimi yapılması gerekmektedir. 
  • Fonksiyon çağrılmadan önce ise parametreler soldan sağa stack'e push edilmesi gerekmektedir.



sample.asm isimli dosya içine yukarıdaki gibi kod yazıldıktan sonra :
  • nasm -f elf32 sample.asm ile object dosya oluşturulur
  • gcc -m32 -o sample sample.o ardından gcc ile çalıştırılabilir dosya oluşturulur.



  • gcc -m32 veya -m64 flaglerini kullandığımızda hata veriyorsa gcc için kurulum yapılması gerekmektedir.




  • apt-get install gcc-multilib kurulumu ile 32 - 64 bit derleme işlemlerini gerçekleştirebiliriz.




sample isimli çalıştırılabilir dosyamız oluşturulmuş oldu. İleride gcc'yi de devre dışı bırakacağız ve doğrudan linker ile elf dosyamızı oluşturacağız.

Assembly' de yazılıp derlenen bir fonksiyonu Windows'ta çağırma

Windows sistemlerde assembly' de yazdığımız bir fonksiyon C içerisinden aşağıdaki gibi çağrılır;


Derleme işlemi yapıldıktan sonra oluşan .obj dosyasını Visual Studio'da açılan C projesine dahil edelim.


 Aşağıdaki gibi örnek bir kod derleme&link işleminin ardından çalıştırıldığında hatasız bir şekilde çalıştığı gözükecektir.


Kısaca fonksiyonun ne yaptığını anlatırsak:
  1. Parametreler stack'e sağdan sola doğru aktarılmış yani fonksiyonla gönderilen iki parametre stack'in üstüne sırasıyla konulmuş.
  2. EBP değeri stack'e konulmuş /*geri dönüş yapıldığında akışın sorunsuz devam etmesi için*/ 
  3. ESP değeri EBP değerine atanmış
  4. EDX'e sağdan ilk parametrenin adres değeri atanmış
  5. EDX'in içinde bir adres bulunmakta bu adresin gösterdiği değer EAX'e atanmış. ( Yani ilk parametrenin değeri EAX'e atanmış )
  6. EAX içindeki değer EBP-4'e konulmuş. ( birinci parametre'nin gösterdiği adresteki değer artık burada )
  7. İkinci parametrenin adresi ECX'e atanmış
  8. İkinci parametrenin değeri EAX'e atanmış
  9. İkinci parametre' nin değeri EDX (edx'in içinde 1. parametrenin adresi var) aracılığıyla 1. parametrenin gösterdiği yere atanmış. (ilk değişim gerçekleşti)
  10. Stack'te saklanan birinci parametre'nin değeri de [ EBP-4 ]  EAX yazmacına atandı. 
  11. ECX yazmacında ikinci parametrenin adresi olduğuna göre şimdi de EAX (birinci parametrenin değeri bunun içindeydi) yazmacındaki değer ikinci parametrenin gösterdiği yere aktarılmış oldu.
  12. EBP'nin değeri de ESP'ye aktarıldı. 
  13. Ardından stack'te tutulan eski ebp değeri de pop ile geri alınmış oldu.  /*geri dönüş yaptığında akışın sorunsuz devam etmesi için*/


Not1: Yukarıdaki işlemlerden anlayacağınız üzere stack'i düzenleme işi çağrılan (callee) fonksiyon tarafından gerçekleştirilmiştir. Fonksiyon çağrılarında stack düzenlemesi önemli bir konudur ve ileride daha detaylı anlatılacaktır.

Not2: Bu swap işlemi daha basit şekilde yazılabilmektedir. Bu yazıda en kısa biçimde kod yazılmaya çalışılmamıştır. 

32 Bit Linux Sistemler için "Hello World" Assembly Programı


Linux sistemlerinde assembly diliyle "Hello World" programının kodu aşağıdaki gibidir.


1 numaralı kod parçası ekrana yazı yazan,
2 numaralı kod parçası ise programdan çıkış işleminin yapıldığı kısımdır.

Linux’taki merhaba dünya programı Windows’takine göre daha sadedir. Bunun nedeni Linux’ta sistem fonksiyonlarının dinamik kütüphaneden değil kesme (interrupt) yoluyla çağrılıyor olmasıdır. Bu nedenle ekrana yazı yazdırmak için "sys_write", programı sonlandırmak için de "sys_exit" isimli sistem fonksiyonu çağrılmıştır. Sistem fonksiyonları çağrılmadan önce onların parametreleri yazmaçlara yerleştirilmektedir. Her sistem fonksiyonunun bir numarası vardır. Çağrılacak sistem fonksiyonunun numaraları 32 bit sistemde EAX yazmacına yerleştirilir. Sonra sırasıyla EBX, ECX, EDX yazmaçlarına da fonksiyonun parametreleri yerleştirilmektedir. Örneğin void sys_exit(int exitcode) fonksiyonu şöyle çağrılmıştır; Yukarıdaki iki numaralı kod parçasında görüleceği üzere eax yazmacına 1 atanması sys_exit fonksiyonunu temsil etmekte, ebx yazmacına 0 atanması ise exitcode parametresine 0 değerinin gönderildiğini ve int 80h kesmesi ile de fonksiyonun çağrıldığını (call) temsil eder. Şimdilik bu kadar bilinmesi yeterlidir. Linux’taki sistem fonksiyonlarının çağrılma biçimi daha sonra detaylı biçimde anlatılacaktır.


1. kısım derleme işlemidir. Derleme işlemi için nasm programı kullanılmıştır.
2. kısım link işlemidir. Linker ise GNU projesi kapsamında geliştirilmiş olan Linux’un temel linker programı "ld" isimli programdır. ld programı kullanılırken –o seçeneği ile çalıştırılabilen dosyaya isim verilmiştir. Eğer link sırasında çalıştırılabilen dosyaya isim verilmezse default olarak a.out ismi kullanılır. Ayrıca Linux sistemlerinde "ld" programı ile link işlemi yapılırken "entry point" verilmediğine dikkat ediniz. "ld" linker’ı default olarak _start adresini "entry point" olarak almaktadır. Link işlemi bittikten sonra yukarıda görüleceği üzere programımız başarıyla çalışmış ve ekrana Hello World yazısı yazdırılmıştır.