2017-11-06 9 views
0

일부 어셈블리 코드에 문제가 있습니다. 다른 어셈블리 파일의 함수를 사용하여 문자열을 출력하려고합니다. 그러나 문자열을 출력하는 것이 아니라 "S"를 출력합니다. 이 문제를 어떻게 해결할 수 있습니까? NASM 어셈블러를 사용하고 있다고 덧붙이고 싶습니다. 코드 : string.asm인쇄 기능을 % i에 포함 시키면 부팅 섹터가 잘못 인쇄됩니다.

print_string: 
pusha 
mov ah, 0x0e 
loop: 
     mov al, [bx] 
     cmp al, 0 
     je return 
     int 0x10 
     inc bx 
     jmp loop 

return: 
    popa 
    ret 

boot_sector.asm - 부트 섹터의

[org 0x7c00] 

%include "string.asm" 

mov bx, [my_string] 
call print_string 

my_string: 
db 'hello world', 0 

times 510 - ($ - $$) db 0 

dw 0xaa55 
+0

어떤 어셈블러를 사용합니까? – fuz

+0

'cmp al, 0' 대신'test al, al'을 시도하십시오. 여러분의 어셈블리 언어가'offset'이나 그와 비슷한 것을 쓰지 않는다면 메모리 피연산자로'0'을 해석 할 수 있습니다. – fuz

+0

NASM을 어셈블러로 사용하고 내가 제안한 것을 시도했지만 잘못하지 않는 한 작동하지 않는 것 같습니다. – pgrafhamster

답변

2

실행은 첫 번째 바이트로 시작합니다. 이 경우 첫 번째 명령은 함수의 맨 위에 놓기 때문에 첫 번째 명령이 함수의 맨 위에 있습니다.

코드는 조립하기 전에 수동으로 포함 시켰을 때와 완전히 동일하게 조립됩니다. 그래서 부트 섹터는 정말 :

[org 0x7c00] 

print_string: 
    pusha 
    ... 
    ret 

    mov bx, [my_string]  ; BX = load first 2 bytes of my_string. 
    ; should have been 
    ; mov bx, my_string  ; BX = address of my_string.  mov bx, imm16 
    call print_string 

이 작동하지 않는 이유는 아주 명백해야한다, 당신은 당신이 내장 Bochs와 디버거로 코드를 단일 계단 경우이 나타났습니다 (또는 것 부트 섹터를 디버깅하는 다른 방법). 심지어 단지 분해보고는 당신을 흘려 주기도 수도


솔루션 :. 가 다른 코드%include을 넣어 그것으로 실행 가을을 피하기. 예 : 호출 한 후이를 넣어 :

cli  ; disable interrupts 
    hlt  ; halt until the next interrupt. (except for NMI) 

이 (NMI가 가능하다면, 당신은 jmp에 무한 루프 내부의 hlt를 넣을 수 있습니다.)

이 유일한 버그가 아닙니다. @MichaelPetch가 지적했듯이, 주소를 BX로 바꾸는 대신 문자열에서 2 바이트를로드했습니다.

+0

나는 당신의 솔루션을 시도했지만 Spaz에 대한 프로그램 만 발생했습니다. – pgrafhamster

+0

@pgrafhamster :이 버그를 수정하면 새로운 버그가 발견되었습니다. '콜 '뒤에'hlt '을 넣는 것을 잊지 않았습니까? 또한 귀하의 질문에 Fuz의 의견을보십시오. ** 디버거를 사용하여 코드를 단일 단계로 처리하고 그 작업 내용을 확인하십시오. ** 컴퓨터가 다른 컴퓨터를 시뮬레이션하기에 충분히 강력 해지는이 시대에 그렇게하는 것이 바람직하지 않습니다. –

+1

Peter,'include' 맨 위에이 줄을 다시 보길 원할 것입니다.'mov bx, [my_string]' –