Семинары по курсу «Архитектура ЭВМ и язык ассемблера» учебно-методическое пособие. Часть 1. - Е.А. Кузьменкова_ В.С. Махнычев_ В.А. Падарян (1110587), страница 8
Текст из файла (страница 8)
Величина 0xbeef49была размещена в памяти, начиная с адреса x. При размещении использовалисьдирективы db, что привело к разделению числа на два отдельных байта и явномуразвороту их порядка: первым идет 0xef, затем – 0xbe.x db 0xef, 0xbemovsx eax, word [x]roreax, 4; EAX = 0xfffffbeeПример 4-6 Безусловный модульТребуется вычислить модуль числа, не используя команд условной передачиданных и условной передачи управления.РешениеПусть число, для которого будет вычисляться модуль, уже загружено в регистр eax.Воспользуемся следующими фактами.
Арифметический сдвиг влево на 31 разрядзаполнит знаковым битом весь битовый вектор. В зависимости от того, какое знак учисла был изначально, будет получено либо 0, либо -1.Другой факт заключается в том, что побитовое обращение устанавливает взаимнооднозначное соответствие между отрицательными и неотрицательными числами:not00 00b 0 1 1111bnot00 01b 1 2 1110bnot0110b 2147483646 -2147483647 10 01bnot0111b INT_M AX INT_M IN (-INT_M AX- 1) 10 00bТаким образом, NOT(x) = -(x+1).Третий факт касается свойств Исключающего Или: a 0 a, a 1 a .Эти три факта в совокупности позволяют составить следующий код, реализующийформулу sign( x) ( x sb) sb , где sb – результат арифметического сдвига на 31разряд.
Для положительных чисел xor и sub берут в качестве второго операнда 0,что никак не меняет eax. Для отрицательного числа формула приобретает вид( x 11b ) (1) NOT ( x) 1 x .movsarxorsub50ecx,ecx,eax,eax,eax31ecxecxМанипуляции с отдельными битамиДля манипуляции с отдельными битами используются команды BTS, BTR, BTC,позволяющие устанавливать нужные значения указанному биту операнда.Например:btsop,5 ; Установить в 1 пятый бит операнда opПример 4-7 Установка и сброс отдельных битовДана 32-битная статическая переменная a. Требуется установить в этойпеременной бит 3 в значение 1, сбросить бит 17 в значение 0, а значение бита 23заменить на противоположное.РешениеДля манипуляций с отдельными битами используем инструкции bts, btr, btc.section .bssa resd 1section .textbtsdword [a], 3btrdword [a], 17btcdword [a], 23ЗадачиЗадача 4-1 Знак числаПусть переменная x содержит некоторое целочисленное значение.
Не используяинструкции условного перехода, поместить в регистр eax 1, если x < 0, и 0 впротивном случае.// astatic int x;// bstatic short x;// cstatic char x;Задача 4-2 Обмен битамиВ регистре eax заменить 5 левых битов на 5 правых битов.Задача 4-3 Арифметика без арифметических командПриведите фрагмент ассемблерного кода для вычисления выражений.51// astatic unsigned x, y;y = 32 * x – x / 8 + x % 16;// bstatic long long x;x *= 2;// cstatic int x, y;y = x / 64 + x * 4;Задача 4-4 Интерпретация кодаУкажите значения регистров eax (как десятичное число со знаком) и edx (какдесятичное число без знака) после выполнения следующего фрагмента кода.section .datax dd 0xfeff0201section .textmov cx, word [x + 1]mov ax, cximul ahshl ax, clmovsx eax, axmovzx edx, axЗадача 4-5 Подсчет числа единицПодсчитать количество двоичных единиц в двоичном представлении заданногоцелого неотрицательного числа.Задача 4-6 Подряд идущие единицыВ регистр eax поместить значение 1, если в двоичном представлении заданногоцелого числа встречается подряд 5 единиц, и 0 в противном случае.Задача 4-7 Проверка четностиНе используя команд деления и не меняя значения переменной а, реализоватьпереход на метку L в том и только в том случае, если значение a четно.Задача 4-8 Битовый разворот"Перевернуть" содержимое регистра ЕАХ в битовом представлении.Задача 4-9 SignРеализуйте функцию sign, используя только инструкции MOV, SHR, NEG и OR.52Задача 4-10 Крайний правыйДля данного машинного слова, сформируйте в регистре слово, с единственнымустановленным в 1 битом в позиции крайнего правого 0 исходного слова.Например: 10100111 00001000Задача 4-11 Замена инструкцийНе используя команд ROL, ROR, RCL, RCR и SAR, выписать фрагмент программы наассемблере, реализующий действие указанной команды.а) sar eax, 2d) rol ax, 8b) rol bx, 1e) rcl ebx, 31c) rcr ecx, 1Задача 4-12 Обращение операцийПосле выполнения последовательности команд в регистре EAX было полученонекоторое значение.
Восстановите содержимое ячеек памяти.z dw ___________xor eax, eaxorax, word [z]imul eax, eax, 16; EAX = 0x1ee70535.Управляющие конструкцииБезусловная и условная передача управленияНабор машинных команд IA-32 содержит одну команду безусловного перехода jmpи одну команду условного перехода Jcc, где сс – код условия, связанный ссостоянием флагов регистра EFLAGS (см.
Табл. 6).Таблица 6. Связь кодов условий и арифметических флагов.УсловиеJccОписаниеJEZFРавно / НольJNE~ZFНе равно / Не нольJSSFОтрицательное числоJNS~SFНеотрицательное числоJG~(SF^OF)&~ZFБольше (знаковые числа)JGE~(SF^OF)Больше либо равно (знаковые числа)JL(SF^OF)Меньше (знаковые числа)JLE(SF^OF)|ZFМеньше либо равно (знаковые числа)JA~CF&~ZFБольше (числа без знака)JBCFМеньше (числа без знака)Основным способом организации ветвлений и циклов в ассемблерной программеявляется последовательность из двух действий: (1) выработка значений флаговрегистра EFLAGS и (2) выполнение условного перехода. Первый пункт, как правило,реализуется командой CMP, выполняющей с EFLAGS те же действия, что и командаSUB, но не запоминающей результата вычитания, т.е.
в результате ее выполненияпервый операнд не «разрушается».cmpjeeax, 0.l2; Переход на метку .l2 при eax = 0Значение флагов регистра EFLAGS может быть сформировано не только командойCMP. Для реализации реакции программы на значение какого-то определеннофлага предусмотрены команды JZ, JS, JC, JO, JP (в коде условия указана перваябуква проверяемого флага), выполняющие переход при значении флага 1, и54соответственно команды JNZ, JNS, JNC, JNO, JNP, выполняющие переход принулевом значении флага.В качестве примера рассмотрим реализацию реакции на возможное переполнениепри выполнении сложения двух беззнаковых целых чисел, расположенных врегистрах eax и ebx.add eax, ebxjc .uns_ov; Переход на метку .uns_ov при CF = 1Операции над булевыми переменнымиЕдинственными допустимыми значениями логического типа являются значения 0 и1, они представляют ложь и истину соответственно.
Для хранения логическогозначения компилятор gcc использует один байт.Формально, вычисление управляющих условий в операторах должно приводитьполучению булевской величины, которая затем должна проверяться. Ноархитектура IA-32 позволяет сразу же воспользоваться флагами, выработаннымиарифметическими действиями, что позволяет не использовать лишние, с точкизрения производительности, инструкции.Тем не менее, в некоторых ситуациях необходимо явно использовать тип _Bool.#include <stdbool.h>static _Bool p = true;...p = !p;section .datap db 1section .textxor byte [b], 1В архитектуре IA-32 присутствует инструкция SETcc, которая помещает в свойединственный операнд либо 0, либо 1, в зависимости от выполнения условия,указанного в суффиксе кода операции.
В качестве операнда может выступать какрегистр, так и память, но обязательно размером в один байт.Пример 5-1 Восстановление типа и операции сравненияНиже приведен код на языке Си, где data_t – некоторый целочисленный типданных, а COMP – некоторая операция сравнения. Пусть переменная a расположенав регистре EDX, а переменная b в регистре ECX. По заданному ассемблерному коду,реализующему данную операцию сравнения, требуется восстановить data_t иCOMP (возможно несколько вариантов решения).55int comp(data_t a, data_t b) {return a COMP b;}CMP ECX, EDXSETL ALРешениеПоскольку в инструкции SETcc используется код L, данные, расположенные врегистрах EAX и EDX рассматриваются как 32 разрядные знаковые числа.
В языке Сисоответствующим типом может выступать int или long, причем допустим явнодобавленный спецификатор signed.Операцией сравнения является «>», поскольку код L требует выполнения строгогонеравенства ОП1 < ОП2 в предыдущей инструкции.ОП1 < ОП2 ECX < EDX b < a a > bИтого, имеем следующий вариант допустимого кода.int comp(int a, int b) {return a > b;}Реализация ветвления и циклаТиповым приемом при организации ветвления в операторе if являетсявычисление условия и последующая проверка условия в команде условногоперехода; если условие не выполнилось – переходим на метку, расположеннуюсразу после фрагмента кода, который реализует тело if.static int *p, a;if (p) {a = *p;}mov eax, dword [p]test eax, eaxjz .lmov eax, dword [eax]mov dword [a], eax.l:При реализации оператора if-else можно воспользоваться этим же приемом,слегка его дополнив, а можно закодировать в условной передаче уравненияпереход на ветку «истина», разместив сразу после условной передачи управленияветку «ложь».