2016-03-20 6 views
0

私はルーチンを(コードの一部として)書きましたが、retを取らなければならないときにもretしません。なぜループは停止せずにループし続けますか(ret)? [assembly]

これがルーチンです:

rout3:  lea SI,strtxt ;put the array in indirect addressing register 
      add SI,counter ;add a counter (starts from 0) 
      mov CL,[SI] ;move the character in counter location in the 
          array to CL register 
      mov char,CL ;move the character from the register to an operand 
      inc counter  ;increase counter for the next character (next location) 


      lea BX,arr ;new counter array (size: 256 ascii characters). 
         put the array in the register 
      mov CL,char ;instead of the counter, the ascii value of the 
          character is the location 
      add BX,CX ; add the location (the ascii value- up to 256) 
      inc [BX] ;increase the value of the ascii location (in the array) by one 

      mov CL,strlen ;move the length of the first array (strtxt) to CL register 
      cmp counter,CX ;compare the currect location of the character 
           to the full length of it 
      jb rout3   ;if the location is smaller than the strtxt array length, 
           go to the next character. if not- ret. 
      ret  

私は"jb rout 3"の一部としてretに問題があります。カウンタがstrlen(配列の長さ)と等しいかそれよりも大きい場合でも、ルーチンは再起動します。 お手伝いをしていただきありがとうございました。ご理解いただけるよう、コードの説明を書くのに長い時間がかかりました。

ありがとうございました!

+0

JBは2つのオペランドを_によって使用します。第1オペランドで指定されたビットの値が1の場合、JB命令は第2オペランドに指定されたアドレスに分岐します。この命令の影響を受けるフラグはありません._ [8051命令セットマニュアル](http://www.keil.com/support/man/docs/is51/is51_jb.htm) – MikeT

+0

8051ではなく80x86のように見えますおそらく。以下の場合、JBはjmpです。カウンター(0から始まってインクリメントされる)がCX以下になることはほとんどありません(80x86を使用したことはありませんが、問題はどこにあるのでしょうか)。 – MikeT

+0

@MikeT:これはすべての指示に基づいています。8086/8088 –

答えて

1

このコードは非常に効率が悪いため、達成すべき内容を把握するのは難しいです。コメントは、実際の地方レベルで各命令が何をしているのかを記述しますが、全体的な目標は何ではありません。

AFAICTでは、ループは無限であってはなりません。 inc [counter]/cmp [counter],CXは、最終的には取られないjbとなる。 counterがループ内の他のもので上書きされないと仮定し、inc counterは16ビットオペランドサイズを使用しています(ラベルの後にdwディレクティブが表示されるため、アセンブラには?)、最終的には0xFFFFになりますCXが持つ可能性のある値以下である。

コメントで指摘したように、CHは書かれません。 CLと書いてCXと書いてください。このルーチンがCHに0以外の値を指定して呼び出された場合、必要以上にループします。おそらくxor cx,cxを入力して関数に入る必要があります。


あなただけのレジスタにカウンタを維持し、他の一時値のために(AL /ああ、DL/DHのような)異なるレジスタを使用していない理由を私は理解していません。

このシーケンスは、特に無意味です:

mov char,CL 
... a couple insns that don't touch CX 
mov CL,char 

あなたがCLをこぼさする必要がなかった場合でも、あなたが[SI]を変更しないので、あなただけの、[SI]からそれを再ロードしている可能性があります。または、それが必要とされるまで、最初の場所にロードしないでください。少数の命令と、いくつかのロード/で(それがループの外にいくつかの設定を行うにははるかに効率的だからループを有する


ほとんどの関数は、関数のエントリーポイントに戻ってループをしないので、ループ自体はタイトにすることができますストア)。

+0

ありがとうございました!私は "xor CX、CX"と書いて、それは多くの助けになりました!唯一の問題は、「ret」になっても、再び「call rout3」に移動して、ルーチンをもう一度通らずに次の行に行くのではなく、もう一回rout3を通過することです。これがどうやって起こるか知っていますか? –

+0

@ H.Bi:あなたのコードの残りの部分を投稿していないので、アイデアはありません。 –

+0

ねえ、私は問題を解決しました。今私は別の問題を抱えているので、残りのコードとともに新しい質問ページを開きました。できる場合は、私をそこに助けてください:http://stackoverflow.com/questions/36183130/the-output-is-not-displayed-in-its-entirety-8086-assemblyありがとう! –

関連する問題