2014-10-11 264 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'