Необходимый пример цикла while в Nasm

Может кто-нибудь объяснить мне, как написать цикл While на языке ассемблера NASAM, например, какие регистры задействованы, какие операции перемещения необходимы и как хранится счетчик, я пытаюсь понять сборку, но вначале это немного сложно. .

Спасибо, парни

Кстати: я пытаюсь выучить этот язык для курса, который я беру


person Shawn ricshawnawic    schedule 16.10.2012    source источник
comment
NASM - это не язык, это программа, ассемблер.   -  person Alexey Frunze    schedule 16.10.2012
comment
Верно. Nasm - это ассемблер... и у него есть свой форум - forum.nasm.us Если я отвечу на вопрос здесь, они просто закроют его. :)   -  person Frank Kotler    schedule 16.10.2012


Ответы (3)


Я думаю, вы спрашиваете об ассемблере x86? В ассемблере нет цикла while (возможно, когда-нибудь для этого можно использовать специальные макросы, зависит от ассемблера). Вы должны построить самостоятельно. Вы можете использовать такие команды ассемблера, как

jne, jnz, je, jz, cmp, inc, dec

или какая-то более специальная устаревшая команда

jcxz, loop

Например:

mov ecx,255

L1:

dec ecx
jne L1
ret

В этом примере значение в регистре ecx подсчитывается до 0, после чего цикл выходит из цикла. Другой пример, но который считается выше.

mov ecx,0

L2:

inc ecx
cmp ecx, 255
jne L2
ret
person David J    schedule 16.10.2012
comment
Хорошо. Предположим, если бы я хотел создать гипотетический цикл while, который принимает # предположим 16 и делит его на два, пока частное не станет равным 0, мне нужно будет выполнять сравнение каждый раз, когда число делится на 2. Также я предполагаю, что цикл: метка, а не функция правильная? - person Shawn ricshawnawic; 16.10.2012
comment
В этом случае вы должны просто инициализировать регистр (возможно, eax) тем числом, которое вы хотите разделить на 2. В этом особом случае вы можете использовать сдвиг на один бит вправо (= эквивалентно целочисленному делению на 2) и выйти из цикла если число в eax уже равно 0. И да, вы правы, петля - это метка. - person David J; 16.10.2012
comment
не используйте loop: в качестве метки: это также мнемоника инструкций, поэтому вы получите странные синтаксические ошибки от некоторых ассемблеров. - person Peter Cordes; 08.09.2016
comment
Да, не очень хорошая идея использовать «петлю» в качестве метки. Я исправил ответ. Простите за это. - person David J; 15.12.2016

Циклу нужна начальная точка (возможно, с меткой для удобства), что-то в середине (тело цикла) и инструкция для возврата к началу. Переход может быть условным, чтобы завершить цикл на основе определенных условий, или в теле цикла может быть что-то, что явно завершает цикл, переходя в другое место. Нет никаких конкретных ограничений на то, какие регистры или ячейки памяти или инструкции вы используете, хотя с некоторыми наборами инструкций (например, x86 и x86-64), которые имеют специальные инструкции, разработанные для облегчения написания циклов, и могут иметь некоторые жестко запрограммированные зависимости от определенные регистры. Однако, опять же, нет необходимости использовать их на самом деле.

Кроме того, ваш вопрос достаточно расплывчатый, добавить больше нечего, кроме того, что справочные руководства для программистов от производителя процессора, для которого вы пишете (Intel, AMD, ......) настоятельно рекомендуемые ссылки, которые обычно можно загрузить бесплатно.

person twalberg    schedule 16.10.2012

Многие ассемблеры макросов действительно поддерживают макрос WHILE:

http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_8/CH08-9.html#HEADING9-90

Вот код 6809, написанный Motorola в 70-х:

  WHILE  B,GT,(0,Y) 
    ORA  B,X 
    DECB 
  ENDWH

(Для ясности, единственными «настоящими» кодами операций 6809, которые там используются, являются ORA и DECB.)

person chadwackerman    schedule 08.09.2016
comment
NASM не поддерживает такие вещи. В MASM есть некоторые директивы высокого уровня, такие как IF, и, возможно, циклы, но это вопрос NASM. - person Peter Cordes; 08.09.2016