2016-08-28 10 views
0

アセンブリコードを作成しようとしましたが、文字列を要求し、文字列が印刷される場所から開始し、印刷する長さを指定します。 開始と長さが常に有効であると仮定開始と長さの決定を手伝ってもらえますか?開始と長さのアセンブリ言語を使用した文字列の印刷

それがどのように動作するかを

Enter String: Hello World 
Enter Start: 3 
Enter Length: 5 
Mid-String: llo W 

だから私は、文字列の開始と長さを決定する方法についての問題を抱えています。

.model small 
.stack 
.data 
msg1 db "Enter String:$" 
msg2 db 13,10,"Enter Start:$" 
msg3 db 13,10,"Enter Length:$" 
msg4 db 13,10,"Mid-String:$" 
nwln db 13,10 
mySample label byte 
maxlen db 10 
actlen db 0 
string db 19 dup (?) 
.code 
mov ax,@data 
mov ds,ax 
    lea dx, msg1 ;print msg1 
    mov ah,9 
    int 21h 

    lea dx,mySample ;accept string 
    mov ah,0Ah 
    int 21h 

    mov bh,0 
    mov bl,maxlen 
    mov string[bx],'$' 
    mov ah,9 
    lea dx,string ;print string accept 
    int 21h 

    lea dx, msg2 ;print msg2 and accept start 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov bh,0 
    mov bl,al 

    lea dx, msg3 ;print msg3 and accept length 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov dl,al 

    ;mov maxlen,dl 
    mov bh,0 
    mov bl,maxlen 
    mov string[bx],'$' 
    lea dx,msg4  ;print msg4 
    mov ah,9 
    int 21h 
    lea dx,string ;print mid-string 
    int 21h 
mov ah,4ch 
int 21h 
END 

OUTPUTは次のようになります:私は以下の私のコードに示されているいくつかのことを試してみました、あなたが実際に行う最後のいくつかの指示、で簡単に見に基づいて output from the code above

+0

これをデバッガでシングルステップ実行すると、読み込んだ数値は実際に期待通りにレジスタに格納されますか?最後の 'int 21h'の前にレジスタの値がありますか?そうでない場合は、逆方向に作業して、物事が最初に期待したように動作しなくなった場所を見つけてください。 –

+0

Chouny、あなたの質問に新しい答えがあります。 –

答えて

1

オフセット印刷と(仮定残りのコードは文字列を正確に表示して読み込みます)

ASCIIから整数に変換するのを忘れてしまい、文字列の末尾よりも多くのバイト('0':ASCIIエンコーディング0)。

また、開始オフセットは何も表示されません。 atoi(start_offset_string)をBXに入れた後にlea dx, [string + bx]のようなことをするのは簡単でしょう。

あなたの長さは、オフセット位置からではなく、元の文字列の先頭からカウントされます。最初にオフセットを行いたいかもしれません。

+0

私はそれをまったく手に入れません。私がした文字列の始まりを設定するために数字を受け入れる必要があり、私が置くのはmov blです。 – Chouny

+0

@ Chouny:文字列を出力する直前に、デバッガでコードの部分のBLを調べます。私はあなたのコードでその指示を参照し、私はまだ私の答えが正しいと思います。デバッガなしでasmを書くことは、目隠ししている間にロボットを構築するようなものなので、デバッガを使うことを学ぶと、この答えを理解できます。 –

+0

BX = 000A、これは真であり、BX = 0102、次いで0002、000Aとなる。私は何が起こったのか分からないが、私はそれがスタートかそれほど得られないことを知っている。 – Chouny

0

私はコードを少し変更して動作させましたが、これらの小さな変更は基本的にはポインタ(開始位置と長さのポインタ)を使用して問題になりました。 :

.model small 
.stack 
.data 
msg1 db "Enter String:$" 
msg2 db 13,10,"Enter Start:$" 
msg3 db 13,10,"Enter Length:$" 
msg4 db 13,10,"Mid-String:$" 
nwln db 13,10 
mySample label byte 
maxlen db 10 
actlen db 0 
string db 19 dup (?) 
.code 
mov ax,@data 
mov ds,ax 
    lea dx, msg1 ;print msg1 
    mov ah,9 
    int 21h 

    lea dx,mySample ;accept string 
    mov ah,0Ah 
    int 21h 

    mov bh,0 
    mov bl,actlen ;◄■■■ NOT MAXLEN. 
    mov string[bx],'$' 
    mov ah,9 
    lea dx,string ;print string accept 
    int 21h 

    lea dx, msg2 ;print msg2 and accept start 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov bh,0 
    mov bl,al 
    mov si,bx  ;◄■■■ SAVE BX IN SI, BECAUSE WE WILL NEED 
        ;◄■■■ BX FOR SOMETHING ELSE (SI = "START"). 

    lea dx, msg3 ;print msg3 and accept length 
    mov ah,9 
    int 21h 
    mov ah,1 
    int 21h 
    sub al,30h 
    mov bl,al  ;◄■■■ REPLACE DL BY BL BECAUSE DX WILL 
        ;◄■■■ BE USED TO DISPLAY WITH INT 21H. 
    ;mov maxlen,dl 
    mov bh,0  ;◄■■■ NOW BX = "LENGTH". BUT WE WILL NEED 
    mov di,bx  ;◄■■■ BX AGAIN, SO LET'S MOVE "LENGTH" TO DI. 

    ;mov bl,maxlen 
    add di, si   ;◄■■■ CALCULATE END POSITION. 
    dec di, 1   ;◄■■■ MINUS 1 BECAUSE IT STARTS IN 0. 
    mov string[di],'$' 
    lea dx,msg4  ;print msg4 
    mov ah,9 
    int 21h 
    ;lea dx,string ;print mid-string 
    mov dx,offset string 
    add dx,si 
    int 21h 
mov ah,4ch 
int 21h 
END 
関連する問題