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

发布于 2024-09-06 10:06:05 字数 1438 浏览 0 评论 0原文

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

要搜索的字符串:“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

Can anybody point out why? I can't see the problem.

String to search: "aassaas"

String to search with: "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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小忆控 2024-09-13 10:06:05

我不明白为什么 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 是不必要的 - 考虑如果 R3R3 调用 SUBNE 的效果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.

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

I don't understand why a) you're writing this in assembler instead of C, and b) why you're not using some routine based on strstr. The most likely scenario is that this is a homework problem, or some other form of learning exercise, so I don't want to give too much away. In any event, there are a couple of problems that I noticed. The first bit I notice is in the RESET routine:

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

The CMP is unnecessary - consider what the effect of the SUBNE calls will be if R3 is 0, and you'll see that you can perform the subtractions unconditionally. You want to run ADD R0, R0, #1 unconditionally - in fact, this is a big part of the reason you have an infinite loop. If you get to the RESET subroutine, and R3 is 0, then it doesn't change any state. I also notice that the STMFD / LDMFD pair is really not necessary - LR won't be modified in this subroutine, so it doesn't need to go on the stack.

Next, I notice that you're not careful enough about when to terminate your loop. Consider what happens if you give two empty strings as arguments to SEARCHSTRING. Call it with two empty strings as arguments, and single-step through your assembly code to see the problem. The general form of a for loop, when compiled to assembly, will be something like:

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.

hopefully this will help you to reorganize the code in a more straightforward way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文