2017-06-08 13 views
0

最終的な配列の各単語の間にスペースを挿入するマクロを記述する必要があります。どのように私はこれを達成することができ、どこで初期化して呼び出す必要があります。配列の単語間にスペースを挿入するマクロ

希望出力:「Say Cheese Okay」。これまで

出力: "SayCheeseOkay" これまで

マイコード:

INCLUDE Irvine32.inc 

.data 
seq1 byte 'Sequence1 : ', 0 
seq2 byte 'Sequence2 : ', 0 
seq3 byte 'Sequence3 : ', 0 
fin_seq byte 'Final Sequence : ', 0 
s1 byte 'Say', 0 
s2 byte 'Cheese', 0 
s3 byte 'Okay', 0 
s4 byte 30 dup(?) 

.code 
main PROC 
    cld 
    mov edx, offset seq1 
    call WriteString 
    mov edx, offset s1 
    call WriteString 
    call Crlf 

    mov edx, offset seq2 
    call WriteString 
    mov edx, offset s2 
    call WriteString 
    call Crlf 

    mov edx, offset seq3 
    call WriteString 
    mov edx, offset s3 
    call WriteString 
    call Crlf 

    mov ecx, LENGTHOF s1 
    mov esi, offset s1 
    mov edi, offset s4 

copy1 : movsb 
    loop copy1 

    mov ecx, LENGTHOF s2 
    mov esi, offset s2 
    mov edi, offset s4 
    add edi, LENGTHOF s1 
    sub edi, 1 


copy2: movsb 
    loop copy2 
    mov ecx, LENGTHOF s3 
    mov esi, offset s3 
    mov edi, offset s4 
    add edi, LENGTHOF s1 
    add edi, LENGTHOF s2 
    sub edi, 2 

copy3: movsb 
    loop copy3 
    mov edi, offset s4 
    mov ecx, lengthof s4 
    mov al, ' ' 
    cld 

c1: 
    scasb 
    je c2 
    cmp ecx, 0 
    jz quit 
    loop c1 

c2: 
    cld 
    sub edi, 1 
    stosb 
    jmp c1 

quit: 
    mov ecx, LENGTHOF s4 
    mov esi, OFFSET s4 
    mov ebx, 0 

cycle: 
    mov al, [esi] 
    jmp exl 


exl: 
    movsb 
    loop cycle 
    mov edx, offset fin_seq 
    call WriteString 
    mov edx, offset s4 
    call WriteString 

    call Crlf 
    call ReadKey 
    call ReadChar 

exit 
main ENDP 
END main 
+0

なぜ 'copy1'ループの後に' edi'を再作成しますか? ( 'rep movsb'で置き換えることができます)。それはどんな目的を持っていますか、あるいは単にタスクを簡略化する方法を考えていませんでしたか?一旦ediの使用を "合理化"すると、 'mov al '、' 'stosb'の間にスペースを簡単に入れることができるからです。デバッガのレジスタとコード、実際の動作、および冗長な部分を監視します。修正:実際には、ゼロターミネータもコピーし、その後にスペースを入れることになるので、stosbの代わりに 'movバイトptr [edi-1]、 '''を実行できます。そしてなぜ "マクロ"が必要なのですか? :-o ..あなたがアセンブラを学んでいるだけであれば、マクロは避けてください。 – Ped7g

+0

特別な目的はありません、あなたが言ったように、私はそれがそうでなければそれを行う方法の知識が不足していたので、そのようにしました。私は単に割り当てのためにマクロが必要です:p – yTpo

+0

OK、経験を選ぶのに時間がかかります...これをデバッガとシングルステップで起動し、どのように動作するのかを理解しようとします。メモリが蓄積/構築され、その特定の命令がそのチェーン内で何をするかを示す。単一命令のマクロを作ることは奇妙です。私は 'movi [1] 'を意味のあるマクロにどのように変えるのか分かりません。たぶん、割り当てはもっと複雑なマクロなどを求めていたかもしれません。いずれにせよ、マクロを書くことを奇妙に思っています。基本的に欠けている場合、マクロは小規模の反復ビットを切り捨てるのに役立ちますが、初心者ではありません – Ped7g

答えて

0

マルコは次のようになります。

procedure MACRO ad1 
    mov byte ptr [edi-1],' ' 

ENDM 

を、ちょうどCOPY1後にそれを呼び出しますおよびcopy2メソッドを使用します。 copy1メソッドでsub edi, 1を削除してください。

+1

マクロプロシージャを呼び出さないようにしてください。ソース内のプロシージャは、実際のマシンコードであり、呼び出される可能性があり、ソースコード(他のコードと相対的に)がある同じ場所のマシンコードに格納されます。マクロは、それらを使用する場所に注入されるので、コンパイル前にソーステキストのもう少し複雑な「置き換え」を行うようなものです。したがって、 "プロシージャ"という名前は、そのマクロが何をしているのかを示しておらず、プロシージャには何もありません。私は 'WriteSpaceAtPreviousEdi' =読むことの後に何をするのかを理解するチャンスのようなものに行きます。 – Ped7g

0

面白いことは、(あなたがs1を定義された方法、s2、メモリ内s3で、あなたはこのことにより、単一の一つに、文字列を「連結」できること、であることが効果的にすべてのかかるので、これは、あなたの割り当ての解決策ではありませんプログラマが何をしなければならないかについて注意深く判断し、最適なアルゴリズムを最初に思い出させるならば、アセンブリの中のものがどのように高速になるかをデモンストレーションするだけです...マクロ、特殊なパフォーマンス上の理由によりマクロが必要とされない限り、私自身のコードではプロシージャを使用することになります)。

INCLUDE Irvine32.inc 

.data 
seq1 byte 'Sequence1 : ', 0 
seq2 byte 'Sequence2 : ', 0 
seq3 byte 'Sequence3 : ', 0 
fin_seq byte 'Final Sequence : ', 0 
s1 byte 'Say', 0 
s2 byte 'Cheese', 0 
s3 byte 'Okay', 0 

.code 

DisplayLabelValueEol MACRO labelStrPtr:REQ, valueStrPtr:REQ 
    mov  edx,labelStrPtr 
    call WriteString 
    mov  edx,valueStrPtr 
    call WriteString 
    call Crlf 
    ENDM 

main PROC 
    DisplayLabelValueEol OFFSET seq1, OFFSET s1 
    DisplayLabelValueEol OFFSET seq2, OFFSET s2 
    DisplayLabelValueEol OFFSET seq3, OFFSET s3 
    ; modify s1-s2-s3 memory to work as single concatenated string 
    mov  al,' ' 
    mov  [s2-1],al  ; replace the original s1 zero terminator 
    mov  [s3-1],al  ; replace the original s2 zero terminator 
    ; display result 
    DisplayLabelValueEol OFFSET fin_seq, OFFSET s1 

    call ReadKey 
    call ReadChar 
    exit 
main ENDP 

END main 

(残念ながら、私はMASM + Irvine32をどこにも持っていないので、実際にはテストしなかったので、これがうまくいかないかどうかを教えてください)。

関連する問題