2014-10-11 6 views
1

Как показать строку в 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) –

+0

GAS hello world version: http://stackoverflow.com/questions/ 32508919/как к продукции-а-минимал-биос-привет-мир -boot-sector-with-gcc-that-works-from-a и репозиторий с рабочими примерами: https://github.com/cirosantilli/x86-bare-metal-examples –

ответ

0

Несколько проблем:

Во-первых, ваша строка находится в середине вашего кода, поэтому после выполнения mov dx, text процессор будет пытаться интерпретировать строку 'Hello$' как код, который выглядит примерно так:

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

Как вы можете видеть, оригинальные инструкции int 10h и jmp $ утеряны. Чтобы исправить это, просто переместите переменную 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

+0

Кроме того, вы можете показать мне, как этот код будет выглядеть как простой «Hello world»? Thanks :) – user3478487

+1

Вы использовали 'int 21h', который является службой DOS. При написании ОС эта служба не существует. –

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'