ARM - 搜索字符串时的无限循环

时间:2010-06-22 09:57:10

标签: string assembly arm

有人能指出原因吗?我看不出问题。

要搜索的字符串:“aassaas”

要搜索的字符串:“as”

SEARCHSTRING:
  STMFD SP!, {R4-R7, LR} 

  MOV R6, #0               @Matches found
  MOV R3, #0               @Placeholder     

LOOP: LDRB R4, [R0]        @R4 = String to search
  LDRB R5, [R1]            @R5 = String to search with

  CMP R4, R5               @Do they match?
  ADDEQ R3, R3, #1         @If yes, increase placeholder
  LDREQB R4, [R0, #1]!     @Get next char
  LDREQB R5, [R1, #1]!     @Get next char
  BLNE RESET               @If not, reset placeholder and strings.
                           @R0 is nevertheless initial pos+1
  CMP R5, #0               @Is string to search with at the end?
  ADDEQ R6, R6, #1         @If so, add +1 to matches
  BLEQ RESET               @Reset placeholder and strings.

  CMP R4, #0               @Is the string to search finished?
  BNE LOOP                 @If not, start over.

  MOV R0, R6               @If so, move answer into R0.
  LDMFD SP!, {R4-R7, PC}   @Jump back.

RESET:
  STMFD SP!, {LR}

  CMP R3, #0               @Is the placeholder at 0? (initial position)
  SUBNE R0, R0, R3         @If not, subtract from String to search pos
  SUBNE R1, R1, R3         @And string to be searched pos
  ADDNE R0, R0, #1         @Increment string to search+1 so we don't start at the same spot
  MOVNE R3, #0             @Empty the placeholder

  LDMFD SP!, {PC}          @Jump back

1 个答案:

答案 0 :(得分:2)

我不明白为什么a)你用汇编代替C来写这个,b)为什么你没有使用基于strstr的例程。最可能的情况是这是一个家庭作业问题,或者其他形式的学习练习,所以我不想放弃太多。无论如何,我注意到了一些问题。我注意到的第一个位是RESET例程:

RESET:
  STMFD SP!, {LR}

  CMP R3, #0               @Is the placeholder at 0? (initial position)
  SUBNE R0, R0, R3         @If not, subtract from String to search pos
  SUBNE R1, R1, R3         @And string to be searched pos
  ADDNE R0, R0, #1         @Increment string to search+1 so we don't start at the same spot
  MOVNE R3, #0             @Empty the placeholder

  LDMFD SP!, {PC}          @Jump back

CMP是不必要的 - 如果SUBNER3,请考虑0来电的效果,您会发现可以执行减法无条件的。你想无条件地运行ADD R0, R0, #1 - 事实上,这是你有一个无限循环的重要原因。如果您到达RESET子例程,并且R30,那么它不会更改任何状态。我还注意到STMFD / LDMFD对真的没有必要 - LR在这个子例程中不会被修改,因此它不需要进入堆栈。

接下来,我注意到你对何时终止循环不够谨慎。考虑如果给两个空字符串作为SEARCHSTRING的参数会发生什么。使用两个空字符串作为参数调用它,并单步执行汇编代码以查看问题。编译为汇编时,for循环的一般形式将类似于:

for(initial; comparison; increment) {
  body;
}

INITIAL:
    MOV R0, #0         @initialize variables
    B CONDITION        @jump to condition check
BODY:
    LDR R1, [R0]
INCREMENT:             @really, part of the for-loop body.
    ADD R0, R0, #1
CONDITION:
    CMP BLAH, BLAH     @test-condition
    BLT BODY           @restart loop if condition indicates we should do so.

希望这有助于您以更直接的方式重新组织代码。