2012-05-01 6 views
0

私の 'show_msg'機能が正しく動作しないのはなぜですか?下にある先頭のどんなアドレスpop axになります - このプログラムの場合 -16bit/ASM:int 21hを使用した単純な関数?

org 100h 

push str1 
call show_msg 
pop ax 

mov ah, 4Ch 
int 21h 

show_msg: 
mov ah, 9 
mov bx, sp ;in 16bit bx is the only register that can act as a pointer (besides di and si) 
mov dx, [bx] 
int 21h 
ret 


str1 db 'Hello world!$' 
+0

マシンとオペレーティングシステムは正常に動作するはずですか? – ShinTakezou

+0

16ビットDOSで... – user1091856

答えて

4

は、おそらくほとんどの機能へのエントリー時に[sp]は、リターンコードのアドレスが含まれているため。 mov dx, [bx]mov dx, [bx+2]に変更してください。これにより、関数へのエントリが取得される前にプッシュされた引数の値が取得されます。

1

コードには基本的な欠陥があります。

まず、bpをポインタとして使用することもできます。

bxレジスタではなくbpレジスタを使用してスタックをインデックスする必要があります。 [bp]フォームはデフォルトでSSセグメントを使用し、[bx]フォームはデフォルトセグメントとしてDSを使用します。これは、DS!= SSの場合、ではなく、が[bx]を使用する場合はスタックにプッシュされた値を読み込みますが、他の未定義の値が読み取られることを意味します。

ので、正しいバージョンがある: -

show_msg: 
    mov bp,sp 
    mov ah,9 
    mov dx,[bp+2] 
    int 21h 
    ret 

あなたの関数は、いくつかのローカルストレージを必要とする場合には、一般的な形式は次のとおりです。 -

function: 
    mov bp,sp 
    sub sp,amount of space for local storage 

    some code, parameters are [bp+offset], local data are [bp-offset] 

    mov sp,bp 
    ret 
+0

+1。私はリアルモードのプログラミングをたくさん行っていないので、レジスタのいくつかに割り当てられた "デフォルト"セグメントがあることを忘れる傾向があります。それを整理していただきありがとうございます。 –

0

DXがないため、プログラムが正しく動作しないでしょう"str1"のアドレスを指してはいけません。

まず、str1のアドレスをスタックに挿入します。これはSPが指しています。それは問題ではありません。

str1を出力するために関数 "show_str"を呼び出した後、元のIPの値がSPが指すスタックにプッシュされるため、SPはstr1を指していません。

あなたはSPの変更を認識せず、印刷する文字列のアドレスを格納するはずのDXにSPの値を渡そうとしました。

私は、言語自体の秘密を探っていない限り、あなたの人生を楽にしてくれるので、プログラムを書くのに "普通の"スタイルを使うべきだと私は忠告しています。

これは私のプログラムです。

;file: showmsg.asm (.COM) 
    ;nasm -fbin showmsg.asm -o showmsg.com 

    org 0x100 
    mov ax, cs 
    mov ds, ax 

    mov ax, str1  ;Transmit parameter to show_msg through AX 
    call show_msg 

mov ax, 4c00h 
int 21h 

show_msg:   ;the address offset of the string is stored in ax 
    mov dx, ax  ;DS:DX=string address 
    mov ax, 0900h ;AH=09 
    int 21h 
    ret 
str1: db "Hello, world!$" 
関連する問題