Когда вы упоминаете jmp + body + test, я думаю, что вы говорите о переводе цикла while
на языки высокого уровня. Есть причина для второго подхода. Давайте посмотрим.
Рассмотрим
x = N
while (x != 0) {
BODY
x--
}
Наивный путь -
mov ecx, N ; store var x in ecx register
top:
cmp ecx, 0 ; test at top of loop
je bottom ; loop exit when while condition false
BODY
dec ecx
jmp top
bottom:
Это имеет N условных переходов и N безусловных переходов.
Второй способ:
mov ecx, N
jmp bottom
top:
BODY
dec ecx
bottom:
cmp ecx, 0
jne top
Теперь мы все еще делаем N условных переходов, но делаем только ОДИН безусловный переход. Небольшая экономия, но это может иметь значение, особенно потому, что это в цикле.
Теперь вы упомянули инструкцию loop
, которая по существу
dec ecx
cmp ecx, 0
je somewhere
Как бы ты это сделал? Вероятно, так:
mov ecx, N
cmp ecx, 0 ; Must guard against N==0
je bottom
top:
BODY
loop top ; built-in dec, test, and jump if not zero
bottom:
Это довольно небольшое решение, типичное для процессоров CISC. Это быстрее, чем второй способ выше? Это во многом зависит от архитектуры. Я предлагаю вам немного изучить производительность инструкции loop
в процессорных архитектурах IA-32 и Intel 64, если вы действительно хотите узнать больше.