Странный прыжок в сборке MIPS - PullRequest
4 голосов
/ 07 ноября 2010

Я, наверное, упускаю что-то действительно очевидное здесь, но я перебирал это снова и снова, и я решительно застрял.В приведенном ниже коде $8 увеличивается, только если $2 != $0.Теперь я дважды и трижды проверил, и инструкция beq работает (например, если я изменяю lop на end2, она там и идет).

Однако по какой-то причине $8 увеличивается независимо, даже есливетвь выполнена.

lop:   beq $3, $0, end2
       and $2, $3, $4

       sll $3, $3, 1

       beq $2, $0, lop     

       addi $8, $8, 1

       j lop

Я должен признать, что я в полном замешательстве.

Ответы [ 2 ]

6 голосов
/ 07 ноября 2010

(всегда будет выполняться and после первого beq.)

MIPS имеет явную опасность для трубопровода; к тому времени, когда будет принято решение о переходе (или нет), следующая инструкция уже прошла достаточно далеко через конвейер команд, что она будет выполнена независимо. Это известно как «интервал задержки перехода».

В некоторых случаях вы можете организовать код, чтобы воспользоваться этим; если вы не можете (или не хотите), вы можете просто вставить nop в следующую инструкцию.

Некоторые ассемблеры переупорядочивают код (или вводят nop) для вас - например, gas, ассемблер GNU, делает, если вы не говорите это с директивой .set noreorder. Но вам все равно нужно знать об этом при разборке.

Если вы пишете код без автоматического переупорядочения ассемблером, я рекомендую пометить слот задержки некоторыми дополнительными отступами, чтобы выделить его:

lop:   beq $3, $0, end2
         nop
       and $2, $3, $4

       sll $3, $3, 1

       beq $2, $0, lop     
         nop

       addi $8, $8, 1

       j lop
5 голосов
/ 07 ноября 2010

Команда добавления происходит в слоте задержки ветви из beq.

...