2016-10-20 10 views
0

私はx86アーキテクチャを使用してアセンブリを学習しようとしています。 add、sub、mul、imul、div、idivのような基本的な計算ができます。しかし、結果を印刷しようとすると、文字列にいくつかのスペースがあります。これらの余分なスペースを削除する方法はありますか?私は現在、文字列をループし、空白以外の文字を2番目の文字列に送ることによってそれらを削除しようとしています。これを行う方法であれば、なぜ私のコードは機能しませんか?私は交換(xchg)についてどこかを読んだが、私はそれをどのように使用するか完全にはわかっていない。これはもっと効率的な方法でしょうか?アセンブリx86 Win32

   dtoa  product, eax  ; convert to ASCII characters 
       dtoa  xStart, x 
       dtoa  yContinue, y 
       lea  edi, product 
       mov  ecx, 20h   ; mov hex value of space into ecx 

forStart:  cmp  [edi], ecx  ; compare edi to space 
       jne  addToString 
       add  edi, 4   ; get address of next array element 
       cmp  [edi], 00h  ; cmp value of edi to null 
       je  printResult 
       jmp  forStart   ; loop through for next element 

addToString: mov  ecx, [edi]  ; mov value of edi into ecx 
       add  edi, 4   ; get address of next array element 
       cmp  [edi], 00h  ; cmp value of edi to null 
       je  printResult 
       jmp  forStart   ; loop through for next element 

printResult: output resultLbl, xStart ; output result 

答えて

-1

これはかなり不完全です。 dtoaはx86命令ではないので、それが何をするのかは分かりません(おそらく十進数から文字列への変換ルーチンですが、正確に何が生成され、どのように動作するかはソースや適切なドキュメントがないと謎です)。

product宣言が存在しないか、または記載されていません。

また、「文字列」とは何かを定義することもできません。その後、コード内であなたが行うので

それらのすべてが、重要である。

   mov  ecx, 20h   ; mov hex value of space into ecx 
forStart:  cmp  [edi], ecx  ; compare edi to space 
       jne  addToString 

(ところで、あなたはmov ecx,' 'として最初のものを書くことができます)

cmp [edi],ecxはあなたを' 'でDWORD値を比較し、そうします文字列のUTF-32エンコーディングを使用しますか?古典的なASCIIエンコーディングを使用する場合は、BYTEのみ(cmp [edi],cl)を比較し、1だけ進める(add edi,1)必要があります。

cmp [edi], 00h - >どのサイズの値を比較していないかは、NASMのcmp [edi], BYTE 00hのようなサイズ指定子を使用してください。

addToStringでは4バイトの文字列を取得しますが、どこに追加するのかはわかりませんので、何もしません。再び4バイトの要素を使用するとUTF-32エンコーディングで有効になりますが、何とかASCIIのゼロ終了文字列を使用していると思われますので、代わりにバイトで作業する必要がありますか?

あなたは命令によって命令ステップ、およびレジスタの値がどのように変化するかという概念を取り、興味深いアドレスのメモリ内容トラフメモリビューを(見た場合、こののほとんどは、デバッガで把握することができる場所ediポイントへのスキャン中' 'ため、等)。それに直面して指示参照ガイドを参照して、各指示がどのように正確に機能するかを理解してください。

この質問は、デバッグのための努力(デバッグ)の不足を示しています。

そして最後にあなたの質問(複数可)自体について:あなたはすなわち、それを書いたとして

あなたのコードは正確に動作しません。 「スペース以外の文字を2番目の文字列に送信する」という本来の意図とはまったく関係がありません。

あなたは無関係なコードを書いたのはなぜかというと、おそらく、元の意図をもう少し単純なサブタスク(英語のコメント)に分解し、単純なサブ命令のステップを踏むので、デバッグ中にCPU内で起きていることを元の意図と比較することができます。

xchgは2つの値を入れ替えます。文字列がメモリにどのように格納されているかを理解していれば、そのような命令を文字列操作に使用することもできます。

もっと効率的な方法がありますか?

私はあなたが達成したいとは思っていません。 "現在の出力:____30"(_がスペース)の場合、 "希望の出力:30"、その後実際に文字列を変更する必要はありません、ちょうど最初のスペース文字を数え、 "出力"サブルーチンを与える必要がありますxStart + <space_count>アドレスであるため、スペースを含むバイトが発生しません。あるいは、dtoaの設定があります。ライブラリにC printfのような機能があり、簡単に正確な書式設定ができます。


編集:「伝えるのは難しい」強調:

そして、あなたはコードを保つのコメントはしばしば役に立たない、あるいは間違っています。

addToString: mov  ecx, [edi]  ; mov value of edi into ecx 

まず、それがecxediの値を移動しませんが、メモリ内容の値は致命的な差があるedi、内のアドレスによって指さ。

第2に、あなたは明白なことを述べています、それはその指示です。あなたはむしろ、すなわちあなたの「人間の意図」のコメントでは、アーカイブする必要があります:あなたの人間の意図がオフになるところ

addToString: mov  ecx, [edi]  ; reading 4 ASCII letters of string into ecx 

あなたがそれを行うだろう場合、指摘して容易になるだろう、説明書における実装に比べて、あなたの心のレベルの間違いをあなたに指摘してください。

実際、あなたの代わりに作業コードを書くことは可能ですが、なぜそれがどう違うのか、それがどのように機能するのかを理解することができます...それはあなたの側で多くの努力を必要とします)本当にあなたを助けるために。そして、あなたは問題の努力が不足していることを示します。

関連する問題