Подтвердить что ты не робот

X86 с помощью команды ecx и loop по сравнению с jmp + j <условие>

В настоящее время я изучаю язык ассемблера x86 и задаюсь вопросом, что является лучшим способом для реализации циклов. Один из способов состоял бы в том, чтобы переместить значение в регистр ecx и использовать инструкцию цикла, а другой способ - использовать инструкцию jmp, а затем - тело цикла, а затем условное переключение в конечном итоге в начало тела цикла. Я предполагаю, что первый из них будет иметь лучшую читаемость, но в других случаях я не знаю, зачем его использовать.

4b9b3361

Ответ 1

Когда вы упоминаете тест jmp + body +, я считаю, что вы говорите о переводе цикла 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, если вы действительно хотите узнать больше.