2012-04-15 3 views
2

Hello World 부트 로더에이 코드를 사용하고 있습니다. "Hello world \ n"을 출력하는 대신 'H'를 출력하고 멈 춥니 다. 내가 부하를 인쇄 메시지를 성공적으로 사용했지만이 방법은 동등한 것으로 작동하지 않습니다 이유를 이해할 수 없습니다. 첫 번째 문자 뒤에 Hello World 부트 로더가 걸려 있습니다.

[ORG 0x7c00] 
[BITS 16] 

    xor ax, ax ;make it zero 
    mov ds, ax 

    mov ecx, msg 
bios_print: 
    mov al, [ecx] 
    add ecx,1 
    cmp al, 0 ;zero=end of str 
    je hang ;get out 
    cmp al,100 
    jge hang 
    mov ah, 0x0E 
    int 0x10 
    jmp bios_print 


hang: 
    jmp hang 

msg db 'Hello World', 13, 10, 0 






    times 510-($-$$) db 0 
    db 0x55 
    db 0xAA 

편집

: 난에 [BITS (64)]를 변경 프로그램이 당신이 그것을 코딩 한 방식으로 정확하게 작동하고

+0

왜 컴퓨터를 시작할 때'[BITS 64] '를 사용하여 컴퓨터를 시작할 때 16 비트 모드입니까? – Earlz

답변

4

[16 비트]. ASCII의 소문자 e은 십진수로 101과 동일한 65h으로 표시됩니다. 따라서 e (101)이 al 일 경우 cmp al, 100/jge hang을 실행하면 hang 레이블로 점프합니다. 모든게 괜찮아. :)

에 의해 종료 된 문자열을 확인하고 루프가 끝날 때까지 끝내기 만하면 실제로 문제를 해결할 수 있습니다. 끝. 하지만

개의 추가 팁 :

  • 이 플래그가 (거의) 모든 산술 및 논리 연산 후 설정되어 있는지 기억하십시오. 따라서 add 뒤에 cmp을 수행 할 필요가 없습니다. 특히 점프의 유일한 조건이 플래그 중 하나에 의해 표현 될 수있는 경우 특히 그렇습니다. 이 경우 add ecx, 1/cmp al, 0/je hang은 매우 단순한 add ecx, 1/jz hang으로 바꿀 수 있습니다. 이렇게하면 2 바이트가 절약되므로 부팅 섹터 조건에서 유용합니다.
  • 정말로 BIOS 루틴을 호출 할 때 응용 프로그램에서 사용중인 레지스터를 유지하고 싶습니다. BIOS는 여러 공급 업체에서 제공되며 그 중 일부는 훌륭하게 작동하지 않을 수 있으며 레지스터에있는 것을 파괴 할 수 있습니다. 지시 pusha는 그것을 다만한다. 자신이 직접 작성하지 않은 코드를 호출 할 때 모든 런타임 정보를 보존하는 것이 일반적으로 경험적으로 중요합니다 (그러나 "문명화 된"환경에서는 극단적으로 들릴 수 있지만 BIOS 및 일반 리얼 모드 코드는 그렇지 않습니다).
  • 컴퓨터가 부팅되면 실제 모드입니다. 이 모드의 기본 피연산자와 주소 크기는 16 비트입니다 (주소는 인위적으로 20 비트로 세분화 됨). 물론 레지스터의 32 비트 부분을 사용할 수는 있지만 명령이 발생하기 전에 피연산자 크기 접두사를 생성해야합니다. 이것은 또 다른 바이트이며, 지금은 510 개 밖에 없습니다. :) 따라서 mov ecx, msg은 단순히 중복됩니다. 주소의 오프셋 부분은 16 비트보다 길지 않습니다. add ecx, 1에 대해서도 마찬가지입니다. 두 경우 모두 ecxcx으로 바꿉니다.
  • hlt 명령어를 사용하십시오. 그것은 CPU의 혈압을 훨씬 낮추고 실제로 모든 곳에서 그것을 강조하는 데는 쓸모가 없습니다. hang 레이블 다음에 점프하기 전에 hlt을 붙이기 만하면됩니다.
+0

제 문제를 해결해 주셔서 감사합니다. 나는 지금 정말로 어리 석다. – user1133383