2016-03-20 22 views
0

我写了一个例程(作为代码的一部分),即使它必须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中可以看出,JB使用2个操作数。如果第一个操作数中指定的位的值为1,则JB指令分支到第二个操作数中指定的地址。被测试的位未被修改。没有标志受此指令的影响。[来自[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中使用非零值调用此例程,那么它可能会循环比您想要的次数更多的次数。您可能应该xor cx,cx在输入该函数时将其归零。


我不明白为什么你不只是保持在寄存器中的计数器,并使用不同的寄存器(如人/啊,DL/DH)为其他温度值。

这个序列是特殊的无意义:

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

即使你确实需要洒CL,你可能刚刚从[SI]重新加载它,因为你不修改[SI]。或者直到需要的时候才将它加载到第一个地方。


与环路大部分功能不环回功能的切入点,因为它是更有效的做环以外的一些设置,因此该循环本身可以是紧(以一些指令和一些负载/商店)。

+0

谢谢!我写了“xor CX,CX”,它帮了很多!唯一的问题是,即使它到达“ret”,它也会再次进入“调用rout3”,然后再次通过例程“rout3”,而不是再次通过例程去下一行。你知道这怎么会发生? –

+0

@ H.Bi:不知道,因为你还没有发布你的其他代码。 –

+0

嘿,我解决了我的问题。现在我又遇到了另一个问题,所以我用其余的代码打开了一个新的问题页面。如果可以的话,请帮助我:http://stackoverflow.com/questions/36183130/the-output-is-not-displayed-in-its-entirety-8086-assembly谢谢! –