-2

null で終わる文字列または固定長の文字列を特定のメモリ位置に出力する小さな関数を作成しようとしています。これが私のコードです:

vbrstart:
    xor eax, eax
    mov sp, 0x7a00
    mov bp, 0x6000
    mov ss, ax
    mov ds, ax
    mov es, ax
    xor ebx, ebx
    xor ecx, ecx
    push strict dword initializing
    push strict word 0x0000
    call printmsg
    jmp end


;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
    pop strict dword [store_ret]
    mov [store_cx], cx
    mov [store_esi], esi
    pop cx
    pop esi
    push eax
    push ebx
    mov ah, 0x0E
    mov bx, 0x0007
    cmp cx, 0x0000
    je printnullterm
printgivenlen:
    lodsb
    cmp cx, 0x0000
    je printdone
    int 10h
    dec cx
    jmp printgivenlen
printnullterm:
    lodsb
    cmp al, 0x00
    je printdone
    int 10h
    jmp printnullterm
printdone:
    pop ebx
    pop eax
    mov esi, [store_esi]
    mov cx, [store_cx]
    push strict dword [store_ret]
    ret
printdata:
    store_cx dw 0
    store_esi dd 0
    store_ret dd 0

end:
    hlt
    jmp end

initializing db 10,13,'Initializing...',0

テストすると、無限に出力され、null バイトで停止しません。どこで間違いを犯したのですか?

4

2 に答える 2

2

あなたのコードには 2 つの問題があります。

  • ブートローダーを作成しました。このようなプログラムは、16 ビット実アドレス モードで実行されます。これは、 a からの戻りアドレスがcall単語あり、コードが期待するようなdwordではないことを意味します。

    printmsg:
    pop word [store_ret]
    
  • 危険な方法でスタックをセットアップします。最初に SS レジスタを変更し、その直後に SP レジスタを変更する必要があります。

    xor ax, ax
    mov ss, ax      <<< Keep these together 
    mov sp, 0x7a00  <<< and in this order!
    

これは 16 ビット コードであるため、push/popアドレスを dword にする必要はありません。

push word initializing
...
pop si
于 2016-06-03T16:29:12.633 に答える
1

あなたのスタックは、プッシュとポップのすべてに適切に配置されていません。パラメータの受け渡しとルーチンでの使用を確認してください。まず、ヒントを次に示します。

vbrstart:
xor eax, eax
mov sp, 0x7a00
mov bp, 0x6000
mov ss, ax
mov ds, ax
mov es, ax
xor ebx, ebx
xor ecx, ecx
push strict dword initializing
push strict word 0x0000
call printmsg                   ; near call, only 16 bits ret addr stored
jmp end

;push strict dword memloc
;push strict word length
;call printmsg
printmsg:
    pop strict dword [store_ret]    ; pop dword (ret address + 16 bits- 1st argument)
    mov [store_cx], cx              ; store_cx = 0
    mov [store_esi], esi            ; store_esi = ??
    pop cx                          ; cx = initializing
    . . .
于 2016-06-03T16:18:22.273 に答える