2010-06-22 5 views
0

아무도 지적 할 수 있습니까? 나는 문제를 볼 수 없다. 내가) 대신 C의 어셈블러로이 작성하는 이유를 이해하지 않습니다ARM - 문자열 검색 중 무한 루프

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 

답변

2

"로"및 "aassaas"로 검색

문자열 :

문자열 검색하기 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가 불필요 - R30 경우 SUBNE 호출의 효과가있을 것입니다 무엇을 생각하고, 당신은 당신이 무조건 뺄셈을 수행 할 수있는 것을 볼 수 있습니다 . 무조건 ADD R0, R0, #1을 실행하려고합니다. 실제로 이것은 무한 루프가있는 이유 중 큰 부분입니다. RESET 서브 루틴에 도달하고 R30이면 아무 상태도 변경되지 않습니다. 또한 STMFD/LDMFD 쌍이 실제로 필요하지 않음을 알았습니다. LR은이 서브 루틴에서 수정되지 않으므로 스택을 수행 할 필요가 없습니다.

다음으로, 루프 종료시기에 대해 충분히주의하지 않는다는 것을 알게되었습니다. SEARCHSTRING에 인수로 두 개의 빈 문자열을 제공하면 어떻게 될지 고려하십시오. 두 개의 빈 문자열을 인수로 호출하고 어셈블리 코드를 단계별로 실행하여 문제를 확인합니다.

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. 

는 희망이 좀 더 간단한 방법의 코드를 재구성하는 데 도움이됩니다하십시오 for 루프의 일반적인 형태는 어셈블리로 컴파일 할 때, 무언가 같이 될 것입니다.

+0

제안 해 주셔서 감사합니다. 이것은 실제로 숙제 문제입니다. 이후 ADD를 ADD로 변경하여 조건부 ADDNE 명령을 제거함으로써 문제를 게시했습니다. 그러나 이것을 읽은 후, 나는 디자인에 심각한 결함이 있음을 알았습니다. 선생님이 문자열이 비어 있으면 특별한 일이 일어나기를 원했기 때문에 빈 문자열을 걸러내는 별도의 루틴을 보여주지 않았습니다. tipps에 감사드립니다! 선생님이 보여준 결함에 대해서는 언급하지 않았지만 어쨌든 제 코드를 리펙토링합니다! – IAE