Ассемблер преследует 3 цели: кодокопание (reverse engineering и модификация), оптимизация участков кода, которые выполняются часто, позволяет лучше понять ЯВУ и архитектуру CPU, архитектуру ОС, но программы на ассемблере недостаточно наглядны.
Ассемблер – программа, которая переводит исходный текст в последовательность чисел (инструкций) понятные процессору.
Директивы не переводятся в инструкции процессора, а управляют программой-ассемблером (подсказывают для какого процессора, операционной системы, где находится первая инструкция).
*Процедуры вызываются специальной директивой invoke (за которой следуют): имя процедуры и список параметров, разделенный запятыми. Пример - invoke ExitProcess, 0
.radix 10
.386
.model flat,stdcall
option casemap:none
Includelib kernel32.Lib
ExitProcess proto stdcall :dword
.code
main proc
mov eax,2
add eax,3
Invoke ExitProcess,0
main endp
End main
Директива .386 показывает для какого процессора предназначена программа.
*Директива .model flat, stdcall показывает в какой среде будет исполняться программа (model flat-генерировать код для защищенного режима работы процессора) stdcall – порядок передачи параметров процедуре, вызываемая процедура должна сама заботится о восстановлении стека, первым в стек отправляется последний параметр.
*Директива includelib подключает к ассемблерному тексту файл библиотеки содержащий сведения о процедурах ОС, необходимые для их правильного вызова, например - includelib G:\myasm\lib\kernel32.lib
*Директива proto кратко описывает параметры процедуры. ExitProcess proto STDCALL :DWORD Ассемблер переведет исходный текст на язык процессора только тогда, когда описание параметров при директиве proto соответствует описанию процедуры в библиотеке, а так же параметрам, указанным при вызове процедуры директивой invoke, тогда ret сама ставит необходимое количество byte,ов в конце процедуры (только при вызове через invoke).
Директива end указывает на метку – точку входа в процедуру (программу).
Минимально необходимые ключи при трансляции исходника в исполняемый код ml /c /coff link /SUBSYSTEM:CONSOLE
Стандартные ключи при компиляции программы ml /c /coff /Cp /nologo “%1.asm”
Стандартные ключи при компоновке программы link /SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 “%1.obj”
Линкер, редактор связей, компоновщик, построитель, билдер, линковщик.
Дополнительные, отладочные ключи при компиляции программы ml /c /coff /Cp /nologo /Fm /Zi /Zd
Дополнительные, отладочные ключи при компоновке программы link /SUBSYSTEM:CONSOLE /DEBUG /VERSION:4.0
Ключ /Zi режим отладки (.pdb – program database file) информация для отладчика.
Ключ /Cp ключевые слова и идентификаторы зависимы от регистра. (Тоже самое есть option casemap:none)
Ключ /c создать только объектный файл с расширением «.obj».
Ключ /coff формат стандартный для Win.
Ключ /SUBSYSTEM:CONSOLE определяет тип программы - консольное приложение.
1010 = 1010 + 010 = 1*101 + 0 * 100
Существует три системы счисления, связь между ними — это представления весов с коэффициентами, а именно -
Любое число представляется суммой степеней основания. Максимальные коэффициенты, в разных системах счисления, при степенях на единицу меньше основания (базы) системы счисления.
1016 = 1016 + 016 = 1*161 + 0 * 160
1010=A 1110=B 1210=C 1310=D 1410=E 1510=F
При переводе из одной системы счисления в другую, мы раскладываем на сумму где очередное слагаемое является как можно ближе, к переводимому числу, в максимальной степени нового основания. 24=16+8=2^4+2^3 (2, 4, 8, 16, 32-уже превышает, возвращаемся к 16 + остаток). Это один из двух способов перевода чисел из одной системы счисления в другую (например: из десятеричной в двоичную, 1010 = 810+210 = 2310 + 2110 = 10002 + 00102 = 10102 = A16 ) (10/2 = 5+0: 5/2=2+1: 2/2=1+0).
1: 0000 0
2: 0001 1
3: 0010 2
4: 0011 3
5: 0100 4
6: 0101 5 7: 0110 6 8: 0111 7 9: 1000 -8 8 10: 1001 -7 9 11: 1010 -6 10 12: 1011 -5 11 13: 1100 -4 12 14: 1101 -3 13 15: 1110 -2 14 16: 1111 -1 15
Сумма положительного и соответствующего отрицательного для регистра из 4 битов всегда равна 1 0000 или 16. Для получения двоичного кода -7 необходимо представить в виде двоичного числа разность 16 - |-7|=910 =10012 9+(-9)=16(0)
проверка 7+(-7)=0111+1001=10000=1610 Проделаем то же самое с 8
-8=16-8=8=1000 -дополнение до 16 (MAXd).
MAXd - |-X|= -X (-8)
Обращение битов и добавление единицы.
Замечательные свойства «дополнительного кода»:
1. Существует только один ноль. 0000 -> 1111 +1 –> 0000
2. Знак числа можно менять бесконечное число раз без потерь.
3. Позволяет свести вычитание к сложению. (Свойство аддитивной инверсии. Инверсии относительно сложения.), но оно не устанавливает флаги при заёме или переносе. 3-5
Для нахождения десятичного из отрицательного двоичного нужно найти дополнительный код (определить модуль), преобразовать в десятичное число и дописать минус.
Интерпретация числа в компьютере сильно зависит от КОНТЕКСТА, в котором оно используется! Число 1111, является ли положительным числом 15 или -1 в дополнительном кода знает только программист. Вместимость любого числа битов зависит от типов слагаемых и ожидаемого результата.
Беззнаковые
Для отлавливания переноса при сложении беззнаковых.
Флаг С – переполнение разрядной сетки: при сложении двух положительных (беззнаковых) если результат не уместится. При сложении любых двух отрицательных, он всегда будет устанавливаться.
Устанавливается в случае если при выполнении беззнаковой арифметической операции получается число разрядность которого превышает разрядность выделенного для него поля результата.
При желании можно восстановить правильный результат при сложении двух положительных! Учесть С - флаг переноса 000000 0Ah (C) =000001 0Ah
1111 [15]+1111 [15]=11110 (30)14 -32 [30+2]-1 (0…31)
Для чисел со знаком.
Переполнение при сложении чисел со знаком. Возможно, только при сложении чисел с одинаковыми знаками! Признак: отличие знака суммы от знака слагаемых – слагаемые положительны, а сумма отрицательна и наоборот – об этом сообщит флаг переполнения.
При сложении чисел со знаком переполнение возникает, лишь, когда есть перенос из старшего бита, но нет переноса в старший бит, либо наоборот – когда есть перенос в старший бит, но нет переноса из старшего бита. Переполнение возникает, когда знак обоих слагаемых одинаков. Пусть он отрицателен. Тогда перенос из старшего бита будет всегда. Если он не будет сопровождаться переносом в старший бит, знак суммы будет отличен от знака слагаемых, то есть возникает переполнение. При сложении положительных чисел со знаком, перенос из старшего разряда не возникает никогда, потому что оба разряда нулевые. Но если произойдет перенос в старший разряд, сумма окажется отрицательной, то есть опять возникает переполнение. Во всех остальных случаях будет иметь тот же знак, что и слагаемые, то есть переполнения не будет.
Переполнение возникает (при сложении 4-битовых чисел) когда результат меньше -8 или больше 7.
Такое возможно только при сложении чисел с одинаковыми знаками. Ведь при сложении положительных и отрицательных чисел абсолютная величина результата только уменьшается и выходы за пределы отведенных ему битов не происходит. При сложении 5 и -3 получится 2 число заведомо меньшее 5. И раз уже в регистре уместилась пятерка, то поместится и двойка.
01010 -6
01011 -5
10101 -11
Как восстановить правильный результат сложения чисел со знаком в случае переполнения?
Представим себе, что складываются не N-битные, а (N+1) - битные числа. Тогда переполнения уже не будет, но результат сложения N бит окажется верен, потому что они одинаковы как в (N+1) - битных так и в N-битных числах. Значит нужно только догадываться, каким будет (N+1) бит. А он может быть только равным единице при сложении отрицательных и нулю – при сложении положительных чисел. Поскольку мы знаем, что переполнение ведет к отличию знака суммы от знака слагаемых, (N+1) – й бит всегда получается инвертированием N-го.
При сложении 4 000 000 000+4 000 000 000=EE6B280016 (если рассматривать 4 000 000 000 как большие положительные, то результат не верен, потому что не может уместиться в 32 битах, об этом скажет флаг переноса =1)
Но теми же битами можно записать число -29496729610 и тогда результат сложения DCD65000 верен, равен -58993459210
И умещается в 32 бит, о чем скажет опущенный флаг «О».
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
-8 |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
0 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
|
||||||||||||||||
|
|
6 |
7 |
-8 |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
-8 |
-7 |
-6 |
|
|
|
|
|
|
|
|
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
|
|
|
|
|
|
|
|
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
|
|
|
|
|
|
|
||||||||||||||||||||||||||||
Операции
Беззнаковые
Знаковые
СЛОЖЕНИЕ
ВЫЧИТАНИЕ
Сложение Вычитание(+) + (-) (+) – (-)
~ (-) + (+) (-) – (+)
При разности не происходит заема из несуществующего разряда разрядной сетки. (˅)
Сумма вмещается внутри разрядной сетки. (˅)
(+) + (+) (+) – (+)(-) + (-) (-) – (-)
Сумма может превысить количество разрядов под результат, когда сумма не вмещается (˟)
Разность из меньшего числа большего происходит с заёмом из несуществующего разряда разрядной сетки. (˟)
Беззнаковые
****************************
СЛОЖЕНИЕ Описание - Имеет смысл, когда сумма не превышает размер разрядной сетки выделенного под результат сложения.
Опасность
Превышение разрядной сетки!
Возможные результаты.
Есть два возможных случая. 1. Сумма вмещается внутри разрядной сетки. (˅) Ex. 10+3=13
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
|
||||||||||||||||
2. Сумма может превысить количество разрядов под результат, когда сумма не вмещается (˟) (но не более чем на один разряд).
10+8 = 18 = 2 + (С) = (2+ «16») = MAXd+2
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
1 |
2 |
3 |
|||
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
1 0001 |
1 0010 |
1 0011 |
|||
|
|
|
|
|||||||||||||||||||
Подсказки в случае опасности.
Установка флага переноса.
Выход из опасной ситуации.
При желании можно восстановить правильный результат при сложении двух положительных!
Учесть С - флаг переноса slog1 +slog2 = rez & (C) ~восстановить правильный ответ ~ MAXd + rez
****************************
ВЫЧИТАНИЕ Описание - Имеет смысл, когда уменьшаемое больше вычитаемого, иначе будет заём из несуществующего разряда.
Опасность
Заём из разрядной сетки!
Возможные результаты.
Есть два возможных случая. 1. При разности не происходит заема из несуществующего разряда разрядной сетки. (˅) Ex. 10-3=7
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
|
||||||||||||||||
2. Разность из меньшего числа большего происходит с заёмом из несуществующего разряда разрядной сетки. (˟) (но не более одного разряда) Ex. 3-5= -2= 14 + (С)
14 |
15 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
|
1110 |
1111 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
|
|
|
||||||||||||||||||
Подсказки в случае опасности.
Установка флага переноса.
Выход из опасной ситуации.
При желании можно восстановить правильный результат при вычитании с заёмом из несуществующего разряда разрядной сетки.
umen - vjichit = rez & (C) ~восстановить правильный ответ ~ - (MAXd – rez) [!мое предположение!]
Знаковые
****************************
СЛОЖЕНИЕ
– (разные знаки) Описание - Имеет смысл, в любом из двух вариантов (не важно перескакивает или нет MAXd)
(+) + (-)
(-) + (+)
Опасность
Опасности нет
Возможные результаты.
Есть два возможных случая. 1. может перескочить MAXd, устанавливая флаг переноса, (-1) + 7=6 одинаково что и 7+ (-1) =6
2. а может и нет, но результат операции всегда верен т.к. разные знаки.
7
+ (-1) = 6, что (-1) + 7 = 6 --- перескакивает MAXd
(
-5)
+ 2 = (-3), что 2+(-5) = (-3) --- не перескакивает
MAXd
] ]
-8 |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
-8 |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
|||||||
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
1 |
2 |
3 |
4 |
5 |
6 |
|||||||
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||
Подсказки в случае опасности.
Опасной ситуации нет.
Выход из опасной ситуации.
Опасной ситуации нет.
– (одинаковые знаки) Описание - Имеет смысл, когда результат операции сложения имеет тот же знак что и слагаемые. (+) + (+) = (+) (-) + (-) = (-)
(+) + (+)
(-) + (-)
Опасность
Отличие знака результата от знака обоих слагаемых!
Возможные результаты.
Есть четыре возможных случая.
Когда два положительных складываем (+) + (+) в случае корректного результата (наступает положительный результат) (флаг O не подымается) переход через MAXd никогда не возникнет. (˅)
Когда два положительных складываем (+) + (+) и наступает случай некорректного (наступает отрицательный результат) результата (флаг O подымается), переход через MAXd никогда не возникнет, и сумма растет в диапазоне от 1000 до 1110. (˟)
Когда два отрицательных складываем (-) + (-) в случае корректного результата (наступает отрицательный результат) (флаг O не подымается), но переход через MAXd всегда возникнет. (˅)
Когда два отрицательных складываем (-) + (-) в случае некорректного результата (наступает положительный результат или ноль) (флаг O подымается), но переход через MAXd всегда возникнет, и сумма уменьшается в диапазоне от 1110 до 0000. (˟)
-8 |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
-8 |
-7 |
-6 |
-5 |
-4 |
-3 |
-2 |
-1 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
1 |
2 |
3 |
4 |
5 |
6 |
|||||||
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
1 0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||
Подсказки в случае опасности.
Установка флага переполнения.
Выход из опасной ситуации.
Представим себе, что складываются не N-битные, а (N+1) - битные числа. Тогда переполнения уже не будет, но результат сложения N бит окажется верен, потому что они одинаковы как в (N+1) - битных так и в N-битных числах. Значит нужно только догадываться, каким будет (N+1) бит. А он может быть только равным единице при сложении отрицательных и нулю – при сложении положительных чисел. Поскольку мы знаем, что переполнение ведет к отличию знака суммы от знака слагаемых, (N+1) – й бит всегда получается инвертированием N-го.
ВЫЧИТАНИЕ
– (разные знаки)
… после прочтения главы про subb
– (одинаковые знаки)
…
main proc
mov al,-127
mov bl,-120
add al,bl
mov ax,-127
mov bh,0FFh
add ax,bx
