Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ASMhelp_Kiselev.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
68 Кб
Скачать
☆

1.5 Разыменование

Разыменование - это получение объекта по ссылке.

Ссылка — это объект, указывающий на определенные данные, но не хранящий их

(в частности переменная хранящая адрес объекта).

Когда мы(программисты на ассемблере) обращаемся к регистру или константе, то пишем их имена просто так, обращаясь же к выделенной области оперативной памяти (в секции .data или .bss) мы пишем имя метки в квадратных скобках, но на самом деле, проводим операцию разыменования по отношению к данному адресу.

Объясню на примере, допустим у нас есть массив в секции .data:

section .data

mass: db 4, 8, 15, 16, 23, 42

И мы хотим использовать пятое число из этого массива, тогда пишем [mass+4] или byte [mass+4]. Разберём эту запись по шагам.

Итак, метка mass содержит адрес нулевого элемента массива (или говорят: указывает на нулевой элемент массива), но не является самим элементом — это ссылка.

Прибавляя к метке mass число 4 мы добились того, что общее выражение mass+4 теперь указывает на элемент массива с номером 4 (5 элемент).

Затем мы проводим операцию разыменования, то есть сообщаем ассемблеру, что всё находящееся между квадратными скобками является адресом и нам нужно значение лежащее в памяти по этому адресу.

Тогда значение [mass+4] или byte [mass+4] будет равно 23.

Именно здесь, если попытаться перейти по адресу, к которому нет доступа (в нашем примере это [mass+6] и большие значения: +7, +8 и т.д.) программа выдаёт ошибку Segmentation fault.

Затем, зачем нужны все эти приписки: byte, word, dword? Ответ прост. Если разыменование используется в команде где явно обозначен размер операнда (Как пример mov al, [mass+4]) уточнение размера не требуется, но в некоторых командах (или просто чтобы уменьшить вероятность ошибки) указывается размер данных, которые лежат по адресу, в нашем случае там лежит байт, поэтому byte [mass+4]

Ещё один подводный камень заключается в том, что смещение (то есть эту «циферку с плюсом или минусом») нужно умножать на размер элементов массива.

В случае выше это был байт ((5-1)*1=4) и запись была такой - byte [mass+4] (=23),

Но если бы было так:

section .data

mass: dd 4, 8, 15, 16, 23, 42

То доступ к пятому элементу был бы оформлен исходя из размера в 4 байта ((5-1)*4=16), и запись была бы такой -

dword [mass+16] (=23).

2. Синтаксис nasm

2.1 Базовые команды

1) mov <операнд1>,<операнд2>

Помещает содержимое <операнд2> в <операнд1>

2) add <операнд1>,<операнд2>

Помещает значение суммы операндов в <операнд1>

3) inc <операнд1>

Эквивалентно add <операнд1>,1

4) sub <операнд1>,<операнд2>

Вычитает из <операнд1> <операнд2> и помещает разность в <операнд1>

5) dec <операнд1>

Эквивалентно sub <операнд1>,1

6) mul <операнд1>

Умножает значение регистра A на <операнд1>, и кладёт результат в A(D:A). Размер A (и наличие D) зависит от размера <операнд1>:

6.1) размер <операнд1> = 1 байт

Умножает al на <операнд1>

Кладёт результат в ax (ah:al если быть точным)

6.2) размер <операнд1> = 2 байт

Умножает ax на <операнд1>

Кладёт результат в dx:ax

6.3) размер <операнд1> = 4 байт

Умножает eax на <операнд1>

Кладёт результат в edx:eax

7) div <операнд1>

Делит значение регистра(ов) A(D:A) на <операнд1>, и кладёт результат в A(D:A). Размер A и наличие D зависят от размера <операнд1>:

7.1) размер <операнд1> = 1 байт

Делит ax(ah:al) на <операнд1>

Кладёт результат деления в al

Кладёт остаток от деления в ah

7.2) размер <операнд1> = 2 байт

Делит dx:ax на <операнд1>

Кладёт результат деления в ax

Кладёт остаток от деления в dx

7.3) размер <операнд1> = 4 байт

Делит edx:eax на <операнд1>

Кладёт результат деления в eax

Кладёт остаток от деления в edx

8) not <операнд1>

Инвертирует все биты <операнд1>

9) neg <операнд1>

Умножает <операнд1> на -1

Эквивалентно: not <операнд1> | inc <операнд1>

10) and <операнд1>,<операнд2>

Конъюнктирует побитово <операнд1> и <операнд2>

Кладёт результат в <операнд1>

11) or <операнд1>,<операнд2>

Дизъюнктирует побитово <операнд1> и <операнд2>

Кладёт результат в <операнд1>

12) xor <операнд1>,<операнд2>

Складывает по модулю 2 побитово <операнд1> и <операнд2>. Кладёт результат в <операнд1>. Чаще всего используется как замена mov <операнд1>,0 т.к. Размер последнего после компиляции 5 байт, а размер xor'а 2 байта.

13) push <операнд1>

Помещает <операнд1> в стек

14) pop <операнд1>

Забирает верхушку стека и кладёт в <операнд1>

15) pushad

Сохраняет все регистры в стеке

16) popad

Восстанавливает все регистры в стеке

17) cmp <операнд1>,<операнд2>

Сравнивает <операнд1> и <операнд2>

18) jmp <метка>

Безусловный переход на метку

19) j<усл> <метка>

Условный переход на метку

<усл> задаёт условие (для результата последней операции cmp)

1) e — равно (ne — не равно)

2) a — больше (na, ae — не больше, меньше или равно)

3) b — меньше (nb, be — не меньше, больше или равно)

4) g — больше (ng, ge - не больше, меньше или равно)

5) l — меньше (nl, le - не меньше, больше или равно)

2,3 — для беззнаковых целых

4,5 — для знаковых целых

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]