2012-03-24 8 views
3

Я работаю над ОС реального режима, записывая в сборку и компилируя в плоские .bin исполняемые файлы с NASM.
Я хотел бы написать некоторые из ОСА в C, и поэтому написал программу эксперимента (ctest.c), который я хотел бы получить доступ к строке и вывести первый символ:
16-разрядная программа .com C в реальном режиме OS

void test(); 

int main() { test(); return 0; } 

char msg [] = "Hello World!"; 

void test() { 
    _asm 
    { 
     mov si, word ptr [msg] 
     mov al, [si] 
     mov ah, 0eh 
     int 10h 
    } 
    for(;;); 
} 

Я скомпилированный это с Open Watcom v1.9 с использованием wcl ctest.c -lr -l=COM. Это создает ctest.com. Ядро, которое я написал в сборке NASM, загружает эту программу в 0x2010: 0x0000, устанавливает DS и ES в 0x2000: 0x0000, а затем переходит к 0x2010: 0x0000. Вот как я звонил .COM-программам, написанным на сборке и скомпилированным с nasm -f bin test.asm -o test.com.
Когда я тестирую ОС (используя Bochs), он успешно загружает ctest.com, но распечатывает бессмысленный символ, который не является частью msg [].
У кого-нибудь есть предложения по этому поводу? Я думаю, что строка просто инициализируется не в том месте. Я хотел бы сохранить это как 16-битную ОС.
спасибо!

+2

Первые 128 байт образа памяти .com содержат данные операционной системы, аналогичные CP/M. DOS зависит от этого. Следующие 128 байтов содержат командную строку. Исполнение начинается с 0x100. –

ответ

4

Вы используете неправильные адреса.

Вы либо нагрузки на 0x2000: 0x0100 и перейти к 0x2000: 0x0100 (не забудьте установки DS = ES = SS = 0x2000 и SP = 0 до этого) ИЛИ вы загружаете на 0x2000: 0x0000 (эквивалент 0x1FF0: 0x0100, потому что 0x2000 * 0x10 + 0x0000 = 0x1FF0 * 0x10 + 0x0100 = 0x20000 = адрес физической памяти в реальном режиме) и перейти к 0x1FF0: 0x0100 (не забудьте установить DS = ES = SS = 0x1FF0 и SP = 0 до что).

Причина в том, что скомпилированный код x86, как правило, не является независимым от положения, и если вы его перемещаете, вы должны отрегулировать некоторые смещения данных внутри кода. Очевидно, вы не делали эти корректировки. В простых случаях нечего было корректировать, и вы ушли с неправильными адресами.

EDIT:

На самом деле, вы больше проблем здесь:

  1. mov si, word ptr [msg] должны измениться, чтобы lea si, byte ptr [msg], потому что вы не хотите, чтобы загрузить si с тем, что внутри строки, вы хотите загрузите его с адресом строки.
  2. Код запуска, связанный с вашей программой OW, зависит от DOS и вызывает функции DOS, которых у вас нет при загрузке вашей программы. Посмотрите, как обойти это here.
1

В MS-DOS программы COM были загружены со смещением 0x100. Я бы предположил, что Open Watcom делает это предположение. Я бы предложил загрузить программу COM в 0x2010: 0x0100 и посмотреть, что это делает.

+0

Я просто попробовал это, и это не сработало. Кстати, я использую int 13h ah 2 для чтения секторов с виртуальной дискеты. – user1112148

+0

Последний адрес, очевидно, неверен. –