2010-06-22 2 views
0

Может ли кто-нибудь указать, почему? Я не вижу проблемы.ARM - бесконечная петля при поиске строки

Строка поиска: «aassaas»

Строка для поиска с: «как»

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

Я не понимаю, почему) вы пишете на ассемблере вместо C, и б) почему вы не используете какую-либо рутину, основанную на strstr. Наиболее вероятный сценарий заключается в том, что это проблема домашней работы или какая-то другая форма обучения, поэтому я не хочу слишком много отдавать. В любом случае, есть несколько проблем, которые я заметил. Первый бит я замечаю в СБРОСА рутине:

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 ненужно - считаем, что эффект от SUBNE вызовов будет, если R3 является 0, и вы увидите, что вы можете выполнить вычитания безоговорочно , Вы хотите безоговорочно запустить ADD R0, R0, #1 - на самом деле, это большая часть причины, по которой у вас бесконечный цикл. Если вы попадаете в подпрограмму RESET, а R3 - 0, то это не изменяет никакого состояния. Я также замечаю, что пара /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. 

надеюсь, это поможет вам реорганизовать код более простым способом.

+0

Спасибо за предложения! Это действительно проблема домашних заданий. С тех пор я решил опубликовать вопрос, устранив условную команду ADDNE, изменив ее на ADD. Однако, прочитав это, я заметил, что у меня действительно все еще есть вопиющие недостатки в дизайне. То, что я не показывал, было отдельной процедурой, которая отфильтровывала пустые строки, потому что наш учитель хотел, чтобы что-то особенное произошло, если строка (строки) пуста. Спасибо за подсказки! Хотя учитель не прокомментировал ни один из недостатков, которые вы показали, я все равно реорганизую свой код! – IAE

Смежные вопросы