2014-10-11 263 views
1

當我使用OS時,如何在FASM中顯示字符串。 我能做到這一點(顯示「8」字):FASM操作系統

mov ax, 9ch 
mov ss, ax 
mov sp, 4096d 
mov ax, 7c0h 
mov ds, ax 
;---- actual code: 
mov ah, 0eh 
mov al, 38h 
int 10h 
jmp $ 
;---- 
times 510 - ($-$$) db 0 
dw 0xAA55 

但這並不工作(我得到黑屏):

mov ax, 9ch 
mov ss, ax 
mov sp, 4096d 
mov ax, 7c0h 
mov ds, ax 
;---- 
mov ah, 09h 
mov dx, text 

text: 
db 'Hello$' 

int 10h 

jmp $ 
;---- 
times 510 - ($-$$) db 0 
dw 0xAA55 

請告訴我,我究竟做錯了什麼,以及如何我應該這樣做嗎?

+0

的[打印在NASM一些可能重複 - 建設x86 Bootsector](http://stackoverflow.com/questions/30764183/print-a-number-in-nasm-building-an-x86-bootsector) – 2015-06-16 23:10:52

+0

GAS hello world版本:http://stackoverflow.com/questions/ 32508919 /如何對生產-A-最小-BIOS問候世界-boot-sector-with-gcc-that-works-from-a和一個存儲庫,其中包含工作示例:https://github.com/cirosantilli/x86-bare-metal-examples – 2015-09-11 09:11:42

回答

0

兩個問題:

首先,你的字符串是在你的代碼的中間,這樣在執行mov dx, text後,CPU會盡量解釋字符串'Hello$'爲代碼,這看起來是這樣的:

dec ax 
gs insb 
outsw 
and al, 0cdh 
adc bl, ch 
inc byte [bx+si] 

如您所見,原始int 10hjmp $指令丟失。要解決這個問題,只需將text變量移動到jmp $語句下面。其次,你似乎混淆了DOS功能和BIOS功能。你的第二個代碼塊設置爲使用DOS打印一個字符串(順便說一下,使用int 21h,而不是int 10h)。但是,由於您正在編寫一個操作系統,因此您沒有任何可用的DOS功能;你只有BIOS。相反,您需要手動循環字符串中的字符並打印每個字符,直到達到結尾。一個例子可能是這樣的:

mov si, text 
    mov bx, 0007h ; set page to 0 and color to light gray text on black background 
    mov ah, 0eh ; select single character print service 
printLoop: 
    lodsb ; grab next character from [si] and increment si 
    cmp al, '$' ; check for end of string 
    je printDone ; exit if done 
    ; all parameters are set up - print the character now 
    int 10h 
    jmp printLoop ; run the loop again for the next character 
printDone: 
    ... 
+0

等等,我用AH = 09進行調試.exe,它可以顯示整個字符串。 – user3478487 2014-10-11 18:49:54

+0

另外,你能告訴我這段代碼看起來像展示一個簡單的'Hello world'嗎?謝謝:) – user3478487 2014-10-11 18:54:19

+1

你正在使用'int 21h'這是一個DOS服務。在編寫OS時,該服務不存在。 – 2014-10-11 22:01:17

0

這可以幫助你:

ORG 0x7c00 

start: 
    push cs 
    pop ds   ; ds = None 
    mov si, welcome 
    call printl 
    hlt ;or as you used jmp $ 

welcome db 'Welcome in os', 0 

include 'sysf.asm' 
times 510 - ($-$$) db 0 

db 0x55 
db 0xAA 

和sysf.asm:

;SI is argument to function - string that you want to print out. 
printl: 
    pusha ;copy normal registers 
    xor bx,bx ;clear bx 
    jmp printl001 
printl001: 
    lodsb ;load next bit from si to al 
    or al,al ;check is al = 0 
    jz printl002 ;if al = 0 jump to printl002 
    mov ah, 0x0e ; set ah to 0x0e for 0x10 
    int 0x10 
    jmp printl001 ;continue printing (go again) 
printl002: 
    popa ;put old registers back 
    ret ;go back to place of 'call printl'