Семинары по курсу «Архитектура ЭВМ и язык ассемблера» учебно-методическое пособие. Часть 2. - Е.А. Кузьменкова_ В.А. Падарян_ М.А. Соловьев, страница 4
Описание файла
PDF-файл из архива "Семинары по курсу «Архитектура ЭВМ и язык ассемблера» учебно-методическое пособие. Часть 2. - Е.А. Кузьменкова_ В.А. Падарян_ М.А. Соловьев", который расположен в категории "". Всё это находится в предмете "архитектура эвм" из 2 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст 4 страницы из PDF
Размещение неоднородных (различной длины) полей структуры возможноаналогичным образом, без промежутков, но особенности работы аппаратуры будут проявляться в задержках чтения и записи невыровненных в памяти данных.Современные компиляторы используют байты-заполнители, чтобы поля структурвсегда размещались в памяти на адресах, кратных некоторым числам, в зависимости от типов полей.Правила выравнивания полей зависят от платформы: архитектуры аппаратуры иработающей на ней операционной системы (Таблица 1). Число N в ячейке таблицыозначает, что поле данного типа расположено на расстоянии кратном N от начального (базового) адреса структуры.
Для 32-разрядного кода правила выравниванияв типовых компиляторов ОС Windows и Linux различаются только для типа double. Вслучае 64-разрядного кода часть изменений в правилах обусловлена увеличениеммашинного слова с 4 байтов до 8, вследствие чего меняются размеры указателей итипа long.Таблица 2. Правила выравнивания для полей различных типов .charshortintlongуказательfloatdoublelongdoubleIA-32/Linux–2444444IA-32/Windows–2444484x86_64/Linux–2488488x86_64/Windows–2448488Правила выравнивания полей являются частью ABI – двоичного (бинарного) интерфейса приложений. В ABI входят соглашения между программами, библиотеками и операционной системой, обеспечивающих взаимодействие этих компонентов на низком уровне на данной платформе. В частности, это дает возможностьобъединять в единую работающую программу модули, независимо друг от другаскомпилированные, в том числе различными компиляторами, и даже изначальнонаписанные на различных языках программирования.
В разделах 3 и 4 будет рассмотрена другая важная часть ABI – соглашения вызова функций.21Пример 2-1 Размещение полей структуры в памятиДан тип данных P, описывающий структуру. Компиляция кода выполняется в ОСLinux.typedef struct {int i;char c;int j;char d;} P;Определите размер типа данных P.
Для каждого поля укажите его смещение относительно начала структуры.РешениеПриведем рисунок, демонстрирующий размещение полей структуры в памяти.Первое поле i будет размещено в самом начале памяти, выделенной под структуру; смещение от начала у первого поля всегда 0. Сразу после него будет размещенополе c. Поскольку тип int занимает 4 байта, смещение, на котором окажется поле c– 4; занимает оно один байт, поскольку тип поля c – char.
Следующее поле структуры (поле j) имеет тип int, его размер 4 байта. Расположено оно будет не сразу после поля c, поскольку это нарушает правила выравнивания. Для типа int выравнивание составляет 4 байта, поле j будет размещено на ближайшем смещении, безостатка делящимся на 4. В данном случае это будет смещение 8. Между полями c иj размещено 3 «пустых» байта с целью выравнивания. Последнее поле, поле d, будет размещено сразу после поля j, поскольку его размер один байт (тип char), никакие правила выравнивания к однобайтовым полям не применяются. Таким образом, смещение поля d составит 12. Однако, после этого (последнего описанногов объявлении) поля будут размещены три байта, их цель – выровнять конец всейструктуры по 4-байтной границе.
Вся структура P будет занимать 4 байта, а смещения ее полей будут следующие: 0, 4, 8, 12.22Пример 2-2 Структуры и объединенияСи-программа, использующая структуру figure, была скомпилирована на платформе IA-32/Windows.struct figure {int id;double scale;unsigned char type;union {void* opaque;unsigned char hash[4];int file;} sourceData;struct figure * thumb;};Определите размер типа данныхотносительно начала структуры.figure.Для каждого поля укажите его смещениеРешениеОдним из полей структуры является представитель другого агрегатного типа – объединения. В свою очередь, в объединении одним из полей является массив.
Чтобыопределить правила размещения данных придется двигаться «изнутри наружу»,поскольку правило выравнивания для агрегатного типа определяется как максимум выравнивания всех его полей. В случае массива используется правило выравнивания типа элемента массива, поэтому поле unsigned char hash[4] не создает никаких требований к выравниванию.
Вся память, выделенная для объединенияsourceData, используется полями совместно.Все три поля занимают одни и те же 4 байта, дополнительных байтов в конце нетребуется, т. к. максимальные требования по выравниванию создаются полямиopaque и file.Для всей структуры карта размещения полей выглядит следующим образом.23Перед полем scale необходим дополнительный промежуток для выравнивания по8-байтной границе, как того требуют правила компилятора Microsoft.
Другие заполняющие байты помещены перед полем sourceData (объединение требует выравнивания в 4 байта) и в конце структуры: наличие поля типа double требует, чтобы размер структуры был кратен 8.Пример 2-3 Структуры и объединения в x86_64Структура figure из Примера 2-2 была скомпилирована для 64-х разрядной машины x86_64. Определите ее размер и смещения полей.РешениеСущественное отличие будет заключаться в том, что размер указателей увеличитсяс 4 до 8 байтов. В первую очередь изменения затронут объединение sourceData.Поля hash и file по-прежнему занимают первые 4 байта, но указатель opaque требует уже 8 байтов.
Все объединение, поле sourceData, должно быть выровнено погранице в 8 байтов.Структура figure в результате увеличится в размере до 40 байтов.С 3 до 7 байтов будет увеличено заполнение перед полем sourceData, чтобы оноразмещалось по смещению 24 (кратно 8). Размер поля-указателя thumb увеличится24до 8 байтов.
Добавлять в конец структуры заполнители не придется, т. к. ее размерсразу же оказывается кратен 8.Работа с полямиПри работе с массивом доступ к элементу требовал вычисления адреса в видебаза + смещение, где смещение = масштаб * индекс. В случае со структурой смещениеопределятся при построении карты, так, как это было показано в примерах2-1 – 2-3. Для всех полей объединения смещение нулевое.Пример 2-4 Чтение и запись полейСи-программа, использующая структуруформе IA-32/Linux.creature,typedef struct t_creature {signed char kingdom;signed char phylum;shortclass;intorder;union {int legs;signed char wings;signed char flippers;signed short tentacles;} extremity;double since;} creature, *p_creature;была скомпилирована на плат-static creature grumpyCat;grumpyCat.extremity.legs = 4;static p_creature velociraptor;static double x;x = velociraptor->since;Реализуйте приведенный выше Си-код на языке ассемблера.РешениеВ первую очередь определяем размещение полей в структуре creature.25Если поля в структуре идут в порядке, когда размер не возрастает, то требованияпо выравниванию не усиливаются, что гарантированно обеспечивает размещениеполей с минимальным числом байтов-заполнителей.
Однако в каждом конкретном случае возможности экономии зависят от набора полей. Например, в рассматриваемом примере размер полей, наоборот, не убывает. Тем не менее, промежутки вовсе отсутствуют, и общий размер структуры составляет 20 байтов.section .bssgrumpyCatresb 20 ; Выделяем память под всю структуру – 20 байтовvelocitaptor resd 1 ; Для указателя необходимо 4 байтаxresq 1 ; Для double необходимо 8 байтовsection .textmov dword [grumpyCat + 8], 4movmovmovmovmov;;eax, dword [velociraptor] ;edx, dword [eax+12];dword [x], edx;edx, dword [eax+16]dword [x+4], edxНе забываем использовать спецификаторразмера при пересылке константСперва загружаем указатель на регистр,после чего прибавляем к нему заранееизвестное смещениеПоле extremity расположено по смещению в 8 байтов от начала структуры, все поляобъединения extremity имеют такое же смещение.Во втором фрагменте кода происходит копирование 8 байтовых данных, для чегоприходится выгружать поле since на регистр по частям два раза.
Первый раз пересылались младшие байты, располагаемые в структуре по смещению в 12 байтов. Устарших четырех байтов это смещение увеличивается на 4 и становится 16.Использование команд сопроцессора x87 позволит записать второй фрагмент кодаболее коротко.26mov eax, dword [velociraptor]fld qword [eax+12]fstp qword [x]Битовые поляЕсли для целочисленного поля задан битовый размер, способ его размещениястандартом языка Си не специфицирован и зависит от реализации компилятора.Однако в большинстве случаев компиляторы стараются «запаковать» битовые поля, уменьшив общий размер структуры.Пример 2-5 Взведение и сброс отдельных битовДана структура omg.
Пусть все три битовых поля размещены компилятором в рамках одного 32-разрядного двойного слова, соответствующему типу int, в порядкесвоего объявления в исходном тексте – от младших битов к старшим.struct omgintintint};{a: 3;b: 5;c: 2;Требуется поместить в поле b значение, составленное из битов полей a и c (младшие биты из поля a, старшие биты из поля c), в поле a – старшие 3 бита из поля b, вполе c – младшие 2 бита из поля b.27Решениеsection .bssomg resd 1sectionmovmovandshrmovshl.texteax, dword [omg]edx, eaxedx, 0x300 ; Выделяем поле c в edxedx, 2; Сдвигаем биты c на их место в результатеebx, eaxebx, 3; Сдвигаем биты a на их место в результате (еще; останутся другие биты)and ebx, 0x38; Убираем все биты кроме битов aor edx, ebx; Объединив биты a и c, получим новое; значение поля b на его местеmov ebx, eaxand ebx, 0xe0; Выделяем старшие 3 бита поля bshr ebx, 5; Помещаем их на место - в поле amov ecx, eaxand ecx, 0x18; Выделяем младшие два бита поля bshl ecx, 5; Помещаем их на место поля aor ecx, ebx; Получаем новые значения полей a и c на их местахor edx, ecx; Получаем итоговый результатmov dword [omg], edx ; Сохраняем его в памятиЗадачиЗадача 2-1Пусть для хранения информации об успеваемости студентов определена структура:struct studentInfochar name [25];int aver;int marks [5];};{// ФИО// средний балл за сессию// оценки в сессиюstatic struct studentInfo st;Учитывая, что компиляция производится на платформе IA-32/Windows, выписатьфрагмент ассемблерного кода для формирования значения поля st.aver.Задача 2-2Даны следующие объявления на языке Си:28typedef struct t_personInfo {char name [20]; // ФИОchar sex;// пол ('m' для мужчин, 'w' для женщин)struct date {int day;int month;int year;} db;// дата рождения} personInfo;static personInfo a[100];static int m;Учитывая, что компиляция производится на платформе IA-32/Windows, выписатьфрагмент ассемблерного кода для печати из массива a ФИО всех женщин, деньрождения которых приходится на месяц m.Задача 2-3Пусть дата упакована в виде структуры date и все битовые поля структуры компилятор располагает в рамках 16-ти разрядного слова в порядке их объявления в исходном тексте от младших разрядов к старшим.structintintint};date {day: 5;month : 4;year : 7;static struct date d1, d2;Написать фрагмент ассемблерного кода для решения следующей задачи:а) в переменную d2 записать дату, непосредственно следующую за датой, записанной в переменной d1;б) напечатать 1, если дата d1 предшествует дате d2, и 0 в противном случае;в) напечатать 1, если дата d1 приходится на летний месяц, и 0 в противном случае.Задача 2-4Сформулируйте достаточные требования для того, чтобы заданная структура илиобъединение имели одинаковое расположение полей для всех рассматриваемыхплатформ: 32- и 64-разрядных Windows и Linux.Задача 2-5Пусть даны статические массивы char *name[N], double height[N], double weight[N],где name[i], height[i] и weight[i] задают имя, рост и вес i-го человека.