Операционная система ФАСМ

Как отобразить строку в FASM, когда я создаю ОС. Я могу это сделать (отображает символ «8»):

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

Подскажите пожалуйста, что я делаю не так и как мне поступить?


person user3478487    schedule 11.10.2014    source источник
comment
Версия GAS hello world: stackoverflow.com/questions/32508919/ и репозитория с рабочими примерами: github.com/cirosantilli/x86-bare-metal-examples   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 11.09.2015


Ответы (2)


Пара проблем:

Во-первых, ваша строка находится в середине вашего кода, поэтому после выполнения 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; у тебя только БИОС. Вместо этого вам нужно будет вручную перебирать символы в строке и печатать каждый из них, пока он не достигнет конца. Пример может быть примерно таким:

    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:
    ...
person Drew McGowen    schedule 11.10.2014
comment
Подождите, я использовал AH=09 с debug.exe, и он работал для отображения целых строк. - person user3478487; 11.10.2014
comment
Кроме того, можете ли вы показать мне, как будет выглядеть этот код для отображения простого «Hello world»? Спасибо :) - person user3478487; 11.10.2014
comment
Вы использовали int 21h, службу DOS. При написании ОС эта служба не существует. - person Drew McGowen; 12.10.2014
comment
Я переписал вторую половину своего ответа - person Drew McGowen; 12.10.2014

Это может помочь вам:

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'
person vakus    schedule 16.06.2015