Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект по ЯП_Гайденрайх.doc
Скачиваний:
23
Добавлен:
16.03.2015
Размер:
533.5 Кб
Скачать

Язык Ассемблер. Занятие 2.

Процессор Intel X86.

Ассемблер – язык низкого уровня.

Большинство современных ПК имеют архитектуру совместимую сверху-вниз с процессором Х86.

Причины актуальности изучения ассемблера: искуссный программист способен на ассемблере написать более эффективную программу, чем программы транслированные с языков высокого уровня.

Для специалисто в сфере инофрмационной безопасности актуальность изучения ассемблера высока, в связи с тем, что атаки часто используют уязвимости, имеющиеся с помощью тонкого знания архитектуры ЭВМ.

Интеграция ассемблера в си. Занятие 3.

В СИ имеются средства (СИ – язык системного программирования) интеграции с ассемблером.

Ассемблерные вставки:

#include <iostream.h> #pragma inline

void main() {

int a=10, b=20, c; cout <<”a=”<<a<<”,b=”<<b<<’\n’; asm mov ax,10; - регистр Ах asm mul a; - умножение Ax на а c=_Ax; cout <<”c=”<<c<<’\n’;

asm {

mov ax, a mov bx, b xchg ax, bx mov a, ax mov b, bx }

cout “d=”<<a<<c”,b=”<<b<<’\n’; }

В программе на ассемблере можно обратиться к любому регистру.

mov – пересылка данных

mul – умножение (2 число аккумулируется и туда помещается Ax)

В других реализациях Си может потребоваться чуть-чуть другая реализация вставки ассемблера.

1978г – Intel разрабатывают микропроцессор 8086, 16 разрядный, 1Мбайт ОП

1983г - Intel разрабатывают микропроцессор 80286 – IBM AT

1987г – Intel разрабатывают микропроцессор 80386, 32 разрядный

1993г – Intel разрабатывают микропроцессор Pentium, 64 разрядный

1

X86

993г -Intel разрабатывают микропроцессор Pentium Pro (увеличен объем кеш- памяти)

1997г – Intel разрабатывают микропроцессор Pentium MMX

1997г - Intel разрабатывают микропроцессор Pentium II

1999г - Intel разрабатывают микропроцессор Pentium III

2000г - Intel разрабатывают микропроцессор Pentium IV

2001г - Intel разрабатывают микропроцессор Itanium

2006г - Intel разрабатывают микропроцессор Core 2 Duo – многоядерный

2011г - Intel разрабатывают микропроцессор Pentium G

Оперативная память делится на ячейки по 8 бит = 1 байт, каждая ячейка имеет адрес. Помимо ячеек можно использовать регистры доступ к которым осуществляется быстрее.

В Intel x86 имеются следующие регистры:

  1. регистры общего назначения AX, BX, CX, SI, DI, BP, SP

  2. сегментные регистры CS, DS, SS, ES

  3. счетчик команд IP

  4. регистр флагов Flags

AX-AH, AL BX-BH, BL AX – аккумулятор BX – база CX – счетчик DX – данные SI – индекс источника DI – индекс приемника BP – указатель базы SP – указатель стека

Регистр флагов содержит набор бит, отвечающих за выполнение данных; осуществляется для условных переходов (реализация команд на ассемблере)

CF – флаг переноса ZF – флаг нуля SF – флаг знака

Программа на ассемблере состоит из предложений. Все предложения (кроме комментария ; ) это или директива ассемблера, или машинная команда.

[метка:] <мнемокод> [операнды] [;комментарий]

[<имя>] <директива> [операнды] [;комментарий]

Процессор двухадресный, поэтому большинство команд включают 2 операнда.

ADD A,2; A=A+2 MOV op1,op2; op1=op2 MOV BX,DX; XCHNG op1,op2; op1↔op2 ADD op1,op2; SUB op1,op2; INC op1; op1=op1+1 DEC op1; op1- - MUL op1; умножение целого числа без учета знака IMUL op1; умножение целого числа с учетом знака DIV op1; деление целого числа без учета знака IDIV op1; деление целого числа с учетом знака

Программа на ассемблере состоит из предложений, каждое из которых должны быть на разных строках.

Машинная команда преобразуется в машинный код. Директива – указание самому ассемблеру.

Ассемблер Х86 удобен тем, что использует десятичные числа и двухадресный процессор, следовательно, большинство команд имеют две операнды.

Изменение знака числа NEG op

Представление отрицательных чисел 0101=5

1-ый знаковый разряд. 0 +, 1-

1101= -5 - прямой код для представления отрицательных чисел. Используется редко

Если нужно произвести арифметические действие, то нам придется производить операции над разрядами по одним правилам, а над знаковыми по другим правилам, влияющим на то, как обрабатываются другие разряды.

Вынуждает вносить в устройства ОУ усложнения при прямом кодировании отрицательных чисел.

Еще вариант кодирования – обратный код.

0101 становится 1010= -5

Если мы по обычным правилам двоичной арифметики осуществим сложение, то получится число состоящее из всех 1: 0101+1010=1111;

Дополнительный код: 0101+1011=10000, т.е. +5 + (-5) =0

При этом все разряды обрабатываются по одним и тем же правилам. Почему дополнительный? Представление отрицательного числа дополняет представление какого-то числа до нуля. Используется в процессорах х86

Плохо программисту-человеку, который смотрит на то, что хранится в ячейке.

Без спецсредств сразу и не поймешь, что это за число. Вызывает затруднение перевод чисел.

Если в языках высокого уровня объявляем тип, то мы знаем какой это тип: символ, число с точкой и т.д., то в ассемблере мы имеем дело просто с ячейкой, в которой записаны 1 и 0 а как это истолковывать, за это ассемблер не отвечает, содержимым ячейки может быть число без знака, целое число со знаком, адрес, код символа, код команды. Ассемблер не проверяет типы. Очень в редких случаях проверяет в связи с размерностью того, что хранится.

Команда NEG превращает число в соответствующее отрицательное число.

Организация вычислительного процесса.

Сюда входят команды безусловного и условных переходов, а также команды организации циклов.

Строки могут начинаться с меток - метка – последовательность букв.

MET: A: CYCL:

JMP <метка> – безусловный переход

Кроме прямого перехода с указанием метки в команде, существует косвенный переход - переход по адресу, находящемуся в ячейке.

В ассемблере допустима адресная арифметика.

JMP DX – переход в DX

Есть дисассемблер – отладчик. Умеет превращать машинный код в запись на языке ассемблера этой программы. Отладчик умеет переводить команды из мнемоникив код и назад.

Есть программы условного перехода, которые позволяют программам иметь достаточно сложные действия.

В результате выполнения арифметических и логических команд автоматически формируются значения флагов указывающих на свойства результата, например положительный или отрицательный, равен 0 или нет, есть флаг С – был ли перенос из старшего разряда или нет.

Сформировать значения флагов можно с помощью специальной команды:

CMP op1, op2(операнд 1, операнд 2) – то же самое что вычитание ( SUB op1, op2)

NB! СМР только меняет содержимое регистра флагов. И когда в регистре флагов сформировались значения, мы можем использовать команду условного перехода.

Формат команды в ассемблере – JXX <метка>

XX - от одного до двух символов, указывающих какая именно команда условного перехода.

Е = equal N = not G-greater > для чисел со знаком Lless < для чисел со знаком A- above => для чисел без знака B-below <= для чисел без знака CMP AX,DX JE <мет1> то есть переход, если AX DX равны JNE <мет2> - если не равны

Может быть переход непосредственно по значению флага

JC - переход по флагу CF JZ – переход по флагу ZF

Одна и та же команда условного перехода может иметь в языке ассемблера Intel х86 несколько названий-синонимов.

JL = JNGE – будет при трансляции один и тот же машинный код.

Мнемокод|условие CMP op1,op2|Какие флаги проверяются JE |op1=op2| ZF=1 JNE|op1!=op2|ZF=0

Для чисел со знаком: JL/JNGR|op1<op2|SF!=OF JLE/JNG|op1=<op2|SF!=OF или ZF=1 JG/JNLE |op1>op2|SF=OF ZF=0 JGE/JNL|op1>=op2|SF=OF

Для чисел без знака: JB/JNAE |op1<op2|VF=1 JBE/JNZ|op1<=op2|CF=1 or ZF=1 JA/JNBE|op1>op2|CF=0 and ZF=0 JAE/JNB |op1>=op2|CF=0

Легко заметить, что JE and JZ синонимы

JZ JNZ JS JNS JC JNC JO JNO JP JNP

Команда, проверяющая значение регистра: JCXZ <метка> т.е. если CX равен нуль, то переход на метку.

В общем-то, с помощью команд условного и безусловного перехода уже можно организовать любые разветвления и циклы: BEG: CMP X,0 JLE FIN <тело цикла>

JMP BEG

FIN: … <продолжение программы>

Реализован цикл «Пока (while)».

Если команда перехода не срабатывает, то осуществляется переход к следующей за ней команде.

BEG: …

CMP X,0

JG BEG

Цикл «Do».

В системе Х86 существуют специальные команды для организации циклов. И первый из них это команда LOOP.

Команда LOOP по умолчанию использует регистр CX.

MOV CX,N; N>0

L: …

LOOP L

В конце стоит просто LOOP L. Вычитается 1 из CX и если СХ !=0 переходит на метку L.

Что следует иметь ввиду? Это аналог цикла DO и тело выполнится хотя бы один раз.

Есть команды-пары синонимов LOOPE/LOOPZ и LOOPNE/LOOPNZ Работают аналогично LOOP, но допускают досрочный выход из цикла.

Перед командой LOOPE (LOOPNE) ставится команда меняющая флаг ZF, например CMP.

LOOPE заставляет цикл повториться CX раз, но только если предыдущая команда фиксирует равенство величин, то есть флаг ZF равен 1. LOOPNE = только если флаг равен 0.

Чаще всего LOOPE используется для поиска элемента последовательности, отличающегося от заданной величины.

Вернемся к логическим командам. Есть команды выполняющие конъюнкцию, дизъюнкцию и т.д.

Выполняют поразрядно. 1- истина, 0 –ложь. Первая команда будет NOT – инвертирует число. После NOT ставим INC – дополнительный код. AND op1,op2 – логическое И над двумя операндами TEST op1,op2 – похож на СМР. В результате выполнения устанавливаются флаги, но результат никуда не запоминается. Чаще всего используется для проверки разрядов внутри ячейки. Если нужно сделать переход на метку L, если правые 3 бита регистра нулевые, то можно написать так: TEST AX,111b (b-указывает на то что число двоичное, h-16-тиричное) JZ L

Следующая команда: OR op1, op2 – ИЛИ XOR op1, op2 – ИСКЛЮЧАЮЩЕЕ ИЛИ

Нет команды для очистки ячейки, но можно использовать MOV AX,0, но это не круто. Круто XOR AX,AX.

Довольно большое количество команд связаны со сдвигами.

Издесь существуютлогические сдвиги и арифметические сдвиги.

SHL op,1

SHR op,1

SAR op,1

ROL op,1

ROR op,1

Основное применение – быстрое изменение умножения на степени двойки – удвоение, уполовинивание и т.д. Выполняется быстрее.

RCL and RCF – сдвиг через перенос. Рис 3 SHL AX,CL

Программа на ассемблере – сумма нечетных:

Include “win 32ax.inc” .data sys dw 10; основание системы счисления table dw 1,2,15,45,12,20,60,50, 255,-1 chislov db ‘00000’ строка для записи числа .code Start: mov esi,table mov cx,10; количество элементов xor dx,dx; dx=0 p1: mov ax,[esi] mov bx,ax shr ax,1; proverka na chetnost jae p2; mov ax,bx; восстановление ax add dx,ax; p2: add esi,2; взять след число dec cx JNZ p1 MOV ax,dx call outint; вывод числа invoke ExitProcess,0 outint: mov edi,chislov ;превращает число в строку и вывод add edi, 4 schet: xor dx,dx ;сброс dx div [sys]; в dl попадает остаток от деления add[edi],dl; код ‘0’+цифра dec edi; переход к след цифре or ax,ax ;проверка ax JNZ schet invoke MessageBox, HWND_DESKTOP, chislov, ‘Summa’,MB_OK ret .end Start;

Push op - заносит в стек Pop op - из стека Pusha - складывает содержимое всех регистров

Popa - восстанавливает из стека

Call <метка> - переход к подпрограмме по метке

Ret - вернуть управление по адресу находящемуся на вершине стека