2012-03-24 1 views
3

저는 리얼 모드 OS에서 작업 중이며 어셈블리 작성과 NASM을 사용한 플랫 .bin 실행 파일로 컴파일하고 있습니다.
나는 C의 OS의 일부를 작성, 그리고 내가 첫 번째 문자 문자열을 액세스하고 인쇄하고자하는 실험 프로그램 (ctest.c) 쓴 것 :이 컴파일
16 비트 .com 리얼 모드 OS에서의 C 프로그램

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으로 점프합니다. 이것은 내가 어셈블리에서 쓰여지고 nasm -f bin test.asm -o test.com으로 컴파일 된 .COM 프로그램을 호출 한 방법입니다.
Bochs를 사용하여 OS를 테스트하면 ctest.com을 성공적으로로드하지만 msg []의 일부가 아닌 의미없는 문자가 인쇄됩니다.
누구에게이 제안이 있습니까? 문자열이 잘못된 위치에서 초기화되고 있다고 생각합니다. 나는 이것을 16 비트 OS로 유지하고 싶다.
감사합니다.

+2

.com 메모리 이미지의 처음 128 바이트에는 CP/M과 비슷한 운영 체제 데이터가 들어 있습니다. DOS는 그것에 달려있다. 다음 128 바이트는 명령 행을 포함합니다. 0x100에서 실행이 시작됩니다. –

답변

4

잘못된 주소를 사용하고 있습니다.

당신에 0x2000에서 중 부하 : 0x0100은과에 0x2000로 이동 : 0x0100은이 또는 당신이 0x2000 인에로드 (= SS = 0x2000 인 및 그 이전 SP = 0 DS의 =의 ES를 설정하는 것을 잊지 마세요 일) : 0000 (해당 0x1FF0 : 0x0100 * 0x0000 = 0x1FF0 * 0x10 + 0x0100 = 0x20000 = 실제 모드의 실제 메모리 주소) 0x1FF0 : 0x0100 (DS = ES = SS = 0x1FF0 및 SP = 0 설정을 잊지 마십시오. 그).

이 이유는 컴파일 된 x86 코드가 일반적으로 위치 독립적이지 않기 때문에 코드를 이동하는 경우 코드 내부에서 일부 데이터 오프셋을 조정해야하기 때문입니다. 분명히, 당신은 이러한 조정을하지 않았습니다. 간단한 경우에는 조정할 것이 없었으며 잘못된 주소로 벗어났습니다.

편집 : 사실

, 더 많은 문제가 여기 거기 : 당신은 문자열 내부에 무엇과 si을로드하지 않기 때문에

  1. mov si, word ptr [msg]lea si, byte ptr [msg]로 변경해야합니다, 당신은 원하는 문자열 주소로로드하십시오.
  2. OW로 프로그램에 연결된 시작 코드는 DOS에 의존하며 프로그램을 부팅 할 때 필요없는 DOS 기능을 호출합니다. 이 문제를 해결하는 방법은 here을 참조하십시오.
1

MS-DOS에서 COM 프로그램은 0x100 오프셋에서로드되었습니다. 오픈 와트 콤 (Open Watcom)이 그러한 가정을한다고 생각합니다. 내가 0x2010에서 COM 프로그램을로드하는 것이 좋습니다 : 0x0100 그리고 그게 뭔지 참조하십시오.

+0

방금 ​​시도했지만 작동하지 않았습니다. 그건 그렇고, 난 가상 플로피 디스크에서 섹터를 읽을 int 13h 아 2 사용하고 있습니다. – user1112148

+0

마지막 주소가 분명히 잘못되었습니다. –