Инструкция JMP может быть использована для выполнения циклов. Например, следующий фрагмент кода может использоваться для выполнения тела цикла 10 раз:
1 2 3 4 5 |
MOV CL, 10 L1: <LOOP-BODY> DEC CL JNZ L1 |
Набор инструкций процессора включает в себя группу инструкций цикла для реализации итерации. Основная инструкция цикла LOOP имеет следующий синтаксис:
LOOP label
Где label
— это метка, которая идентифицирует целевую инструкцию. Инструкция LOOP предполагает, что регистр ECX содержит в себе счетчик циклов. Когда инструкция цикла выполняется, регистр ECX уменьшается, точка выполнения программы переходит к метке до тех пор, пока значение регистра ECX (т.е. значение счетчика цикла) не достигнет нуля.
Вышеприведенный пример можно записать следующим образом:
1 2 3 4 |
mov ECX,10 l1: <loop body> loop l1 |
А здесь с помощью цикла мы выводим на экран цифры от 1 до 9:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
section .text global _start ; должно быть объявлено для использования gcc _start: ; сообщаем линкеру входную точку mov ecx,10 mov eax, '1' l1: mov [num], eax mov eax, 4 mov ebx, 1 push ecx mov ecx, num mov edx, 1 int 0x80 mov eax, [num] sub eax, '0' inc eax add eax, '0' pop ecx loop l1 mov eax,1 ; номер системного вызова (sys_exit) int 0x80 ; вызов ядра section .bss num resb 1 |
Результат выполнения программы:
123456789:
Такой вопрос. Зачем в примере
Если можно сделать просто inc eax?
первой командой мы переводим значение в регистре еах из строки в число
потом второй увеличиваем само число
потом третьей обратно в строчку чтоб можно было напечатать
майнкрафтер прав. не нужно ничего перводить чтобы использовать inc. Оно просто додаст 1 к регистру eax и получится '1' по ASCII, который в тавблице сразу после '0'