pottie4r
Kilopat
- Katılım
- 9 Haziran 2016
- Mesajlar
- 1.404
- Makaleler
- 2
- Çözümler
- 40
Daha fazla
- Cinsiyet
- Erkek
Merhaba! Bugün sizlerle yeni başlayan arkadaşlarımız için bir hello world bootloader yapacağız...
Öncelikle bize lazım olanlar:
Öncelikle masaüstüne "bootloader.asm" isimli bir belge oluşturuyoruz ve notepad++ ile açıyoruz.
Öncelikle bootloader'ımızın 16 Bit olduğunu belirteceğiz. Bunun için [BITS 16] yazıyoruz.
Ardından, BIOS adresini belirtelim. [ORG 0x7C00]
Şimdi ise asıl işe koyulabiliriz. Öncelikle şunu söyleyeyim;
1-> MOV komutu 1.girdiye 2.girdi değerini yükler...
Örneğin: MOV AH,02H ; Burda AH akümülatörüne 02H değerini yükler.
2-> Peki nedir bu AH,BH,CH vs.
Bunlar için bu slaytı incelemenizi öneririm.
Şimdi geri dönelim.
Öncelikle bir mesaj belirleyelim ve bunu 'msg' olarak kaydedelim.
Şimdi geri kalan kısımda her şeyi ekran görüntüsü atarak anlatmayacağım. Görüntü kirliliği olmaması amacıyla eğer copy-paster iseniz sayfanın sonundan kodu alabilirsiniz.
3-> Şimdi bir jump-point oluşturalım.
printstring adlı bir nokta oluşturalım. (Burayı ekran görüntüsü attım çünkü hiç üstünden geçmemiştim kafanız karışmasın )
Onun içine de bir adet point açalım ve ismini 'printchar' koyalım.
Ve açtığımız printchar pointinden sonra bu kodları yazalım;
Bu bizim ekrana bir harf yazdırmak için kullandığımız fonksiyondur. Normalde AL'nin içindekini yazar fakat şuan AL'nin içinde bir değer yok. Hemen bunu da halledelim.
Bunun için SI dediğimiz kayıta 'msg'yi yani mesajımızı atalım. Yani sayfanın başına [ORG 0x7C00]'dan hemen sonra MOV komutu ile msg'yi SI'ya taşıyalım.
Şimdi ise yeni bir point açıyoruz ve ismini next_char yapıyoruz.
Ona da aynen bu kodları yazıyoruz;
Son görünüm:
En son olarak artık yukarıda bahsettiğimiz print_complete pointini açıyoruz ve sonsuz döngüye sokuyoruz...
Sonsuz döngü için JMP $ kullanılır.
Ana programımız bitti, şimdi sırada bu dosyanın boot edilebilir olduğunu anlatmak!
Sayfanın en alt kısmına (msg'yi tanımladıktan sonraki boşluğa)
TIMES 510 - ($ - $$) db 0
DW 0xAA55
yazmak. Artık işimiz bitti! Şimdi bunu kaydediyoruz ve NASM'ın kurulu olduğu yere atıyoruz.
Ardından bir komut istemi açıyoruz ve cd komutu ile NASM'ın kurulu olduğu yere gidiyoruz.
Ve cmd'ye
Ardından oluşan dosyayı QEMU'nun kurulu olduğu klasöre atıyoruz.
Ve sonunda amacımıza ulaştık
İşte gördüğünüz gibi Assembly'da Hello World yazmak
cout << "Hello World!"; yazmaya benzemez
Buraya birkaç işe yarar link bırakıyorum:
Bir dahaki rehberde görüşmek üzere! Hoşçakalın...
Copy-pasterlar için kodun tamamı:
Öncelikle bize lazım olanlar:
- NASM
- Notepad++
- QEMU (test etmek için)
Öncelikle masaüstüne "bootloader.asm" isimli bir belge oluşturuyoruz ve notepad++ ile açıyoruz.
Öncelikle bootloader'ımızın 16 Bit olduğunu belirteceğiz. Bunun için [BITS 16] yazıyoruz.
Ardından, BIOS adresini belirtelim. [ORG 0x7C00]
Şimdi ise asıl işe koyulabiliriz. Öncelikle şunu söyleyeyim;
1-> MOV komutu 1.girdiye 2.girdi değerini yükler...
Örneğin: MOV AH,02H ; Burda AH akümülatörüne 02H değerini yükler.
2-> Peki nedir bu AH,BH,CH vs.
Bunlar için bu slaytı incelemenizi öneririm.
Şimdi geri dönelim.
Öncelikle bir mesaj belirleyelim ve bunu 'msg' olarak kaydedelim.
Şimdi geri kalan kısımda her şeyi ekran görüntüsü atarak anlatmayacağım. Görüntü kirliliği olmaması amacıyla eğer copy-paster iseniz sayfanın sonundan kodu alabilirsiniz.
3-> Şimdi bir jump-point oluşturalım.
printstring adlı bir nokta oluşturalım. (Burayı ekran görüntüsü attım çünkü hiç üstünden geçmemiştim kafanız karışmasın )
Onun içine de bir adet point açalım ve ismini 'printchar' koyalım.
Ve açtığımız printchar pointinden sonra bu kodları yazalım;
Kod:
MOV AH,0Eh ; Bu tele-type fonksiyonu içindir.
INT 10H ; Bu da BIOS'un görüntü interrupt'u
;INTERRUPT LİSTESİ İÇİN : https://en.wikipedia.org/wiki/BIOS_interrupt_call
Bu bizim ekrana bir harf yazdırmak için kullandığımız fonksiyondur. Normalde AL'nin içindekini yazar fakat şuan AL'nin içinde bir değer yok. Hemen bunu da halledelim.
Bunun için SI dediğimiz kayıta 'msg'yi yani mesajımızı atalım. Yani sayfanın başına [ORG 0x7C00]'dan hemen sonra MOV komutu ile msg'yi SI'ya taşıyalım.
Şimdi ise yeni bir point açıyoruz ve ismini next_char yapıyoruz.
Ona da aynen bu kodları yazıyoruz;
Kod:
MOV AL,[SI] ; Dediğimiz gibi printchar "AL" nin içindekini yazıyor. Biz de AL'ye [SI]'yı yükledik.
OR AL,AL ; Burda "AL ?= 0" işlemini yapıyoruz yani "AL" 0 mı? diye kontrol ediyoruz.
JZ print_complete ; Eğer 0 ise ki bu da yazıyı yazdırmayı tamamladı demektir, print_complete pointine gitmesini sağlıyoruz(Onu da birazdan oluşturacağız kafanız karışmasın.)
;artık eğer değilse kısmına geçiyor burası
CALL printchar ; Daha önce tanımladığımız printchar fonksiyonunu çağırıyoruz ve AL'deki harfi yazdırıyoruz.
INC SI ;SI'ın kendisini bir arttırarak bir sonraki harfe geçişi sağlıyoruz.
JMP next_char ; ve bu pointi kelime bitene kadar tekrar çalıştırıyoruz.
;JMP -> pointe gider
;JZ -> IF'den sonra kullanılır. JMP ile aynı işlevi görür.
;CALL -> daha önceden tanımladığınız pointteki kodları çağırır.
Son görünüm:
En son olarak artık yukarıda bahsettiğimiz print_complete pointini açıyoruz ve sonsuz döngüye sokuyoruz...
Sonsuz döngü için JMP $ kullanılır.
Ana programımız bitti, şimdi sırada bu dosyanın boot edilebilir olduğunu anlatmak!
Sayfanın en alt kısmına (msg'yi tanımladıktan sonraki boşluğa)
TIMES 510 - ($ - $$) db 0
DW 0xAA55
yazmak. Artık işimiz bitti! Şimdi bunu kaydediyoruz ve NASM'ın kurulu olduğu yere atıyoruz.
Ardından bir komut istemi açıyoruz ve cd komutu ile NASM'ın kurulu olduğu yere gidiyoruz.
Ve cmd'ye
Ardından oluşan dosyayı QEMU'nun kurulu olduğu klasöre atıyoruz.
Ve sonunda amacımıza ulaştık
İşte gördüğünüz gibi Assembly'da Hello World yazmak
cout << "Hello World!"; yazmaya benzemez
Buraya birkaç işe yarar link bırakıyorum:
BIOS interrupt call - Wikipedia
en.wikipedia.org
INT 10H - Wikipedia
en.wikipedia.org
Bir dahaki rehberde görüşmek üzere! Hoşçakalın...
Copy-pasterlar için kodun tamamı:
Kod:
[BITS 16]
[ORG 0x7C00]
MOV SI,msg
CALL next_char
printchar:
MOV AH,0x0E ; Bu tele-type fonksiyonu içindir.
MOV BL,0x06
INT 10H ; Bu da BIOS'un görüntü interrupt'u
RET
;INTERRUPT LİSTESİ İÇİN : https://en.wikipedia.org/wiki/BIOS_interrupt_call
next_char:
MOV AL,[SI] ; Dediğimiz gibi printchar "AL" nin içindekini yazıyor. Biz de AL'ye [SI]'yı yükledik.
OR AL,AL ; Burda "AL ?= 0" işlemini yapıyoruz yani "AL" 0 mı? diye kontrol ediyoruz.
JZ print_complete ; Eğer 0 ise ki bu da yazıyı yazdırmayı tamamladı demektir, print_complete pointine gitmesini sağlıyoruz(Onu da birazdan oluşturacağız kafanız karışmasın.)
;artık eğer değilse kısmına geçiyor burası
CALL printchar ; Daha önce tanımladığımız printchar fonksiyonunu çağırıyoruz ve AL'deki harfi yazdırıyoruz.
INC SI ;SI'ın kendisini bir arttırarak bir sonraki harfe geçişi sağlıyoruz.
JMP next_char ; ve bu pointi kelime bitene kadar tekrar çalıştırıyoruz.
;JMP -> pointe gider
;JA -> IF'den sonra kullanılır. JMP ile aynı işlevi görür.
;CALL -> daha önceden tanımladığınız pointteki kodları çağırır.
print_complete:
JMP $
msg db 'Hello World!',0
TIMES 510 - ($ - $$) db 0
DW 0xAA55