Помощь в написании студенческих работ
Антистрессовый сервис

Особенности программирования на языке Assembler

КонтрольнаяПомощь в написанииУзнать стоимостьмоей работы

В нашу жизнь уже давно вошли процессоры с 64-х разрядной архитектурой. Не смотря на то, что все еще активно используются 32-х разрядные процессоры, и что программ для них в разы больше, новая архитектура приобретает все больше поклонников. 64-х разрядные процессоры позволяют использовать больше ресурсов, чем 32-х разрядные, позволяют оперировать с большим количеством данных за единицу времени… Читать ещё >

Особенности программирования на языке Assembler (реферат, курсовая, диплом, контрольная)

Оглавление Введение

1. Основные отличия архитектур i686 и amd64

2. Общие принципы программирования на языке Assembler для платформ i686 и amd64

Регистры Принцип передачи параметров в функции Работа со стеком Адресация

3. Листинг программы для сравнения архитектур i686 и amd64

4. Пример работы программы

5. Сравнение программ Вывод Список литературы

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

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

В данной работе будет приведено сравнение особенностей программирования для 32-х разрядных и 64-разрядных процессоров на языке ассемблера. В качестве ОС будет применяться операционная система Ubuntu 12.10 LTS, компилятор gcc. Также мы будем придерживаться AT&T нотации языка программирования Assembler.

1. Основные отличия архитектур i686 и amd64

Нововведения в архитектуре 64-х разрядных процессоров позволили значительно увеличить объем используемой памяти для одного ядра процессора .

Таблица 1. Общие ограничения на память

Характеристика

32-разрядные модели

64-х разрядные модели

Виртуальное адресное пространство (один роцесс)

4 ГБ

16 ТБ

Виртуальное адресное пространство (32-х разрядный процесс)

2 ГБ (3 ГБ, при запуске системы с ключом /3GB)

4 ГБ

Виртуальное адресное пространство (64-х разрядный процесс)

;

8 ТБ

Пул подкачиваемой памяти (режим ядра)

470 МБ

128 ГБ

Пул неподкачиваемой памяти (режим ядра)

156 МБ

128 ГБ

Элемент системной таблицы страниц

660−900 МБ

128 ГБ

Также использование 64-х разрядной архитектуры позволяет обращаться к большему количеству регистров большего объема во время работы программы. Если при использовании 32-х разрядного режима мы могли обращаться к восьми 32-х разрядным регистрам общего назначения: EAX, EBX, ECX, EDX, EBP, ESI, EDI, ESP, к восьми 64-х разрядным регистрам для работы медиа данными и с числами с плавающей точкой: MMX0/FPR0, MMX1/FPR1, MMX2/FPR2, MMX3/FPR3, MMX4/FPR4, MMX5/FPR5, MMX6/FPR6, MMX7/FPR7, к флаговому 32-х разрядному регистру EFLAGS и к 32-х разрядному регистру-указателю на следующую инструкцию EIP, то в 64-х разрядном режиме у нас гораздо больше возможностей:

* Регистры общего назначения были расширены до 64-х разрядов с сохранением старой структуры и получили названия RAX, RBX, RCX, 3RDX, RBP, RSI, RDI и RSP;

* Были введены новые 64-х разрядные регистры в количестве восьми штук: R8, R9, R10, R11, R12, R13, R14, R15;

* Флаговый регистр и регистр-указатель на следующую инструкцию процессора были расширены до 64-х разрядов и получили названия RFLAGS и RIP соответственно;

* Было добавлено 16 128-разрядных медиа-регистров под названиями XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15.

Из вышесказанного можно сделать вывод о том, что использование 64-х разрядной архитектуры позволит более быстро, качественно и удобно решать поставленные как научные, так и общие задачи.

Стоит заметить, что результаты тестирования программ на различных платформах показывают, что в большинстве случаев использование 64-х разрядной архитектуры дает прирост производительности, по сравнению с 32-х разрядной архитектурой.

2. Общие принципы программирования на языке Assembler для платформ i686 и amd64

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

Регистры

Использование 64-х разрядных регистров позволяет на единицу времени передавать гораздо больше информации. Если, в случае 32-х разрядной архитектуры, мы можем передать 32 бита информации за раз (максимальное число 4 294 967 296), то в случае 64-х разрядной архитектуры мы можем передать максимальное значение, равное 18 446 744 073 709 551 616.

Листинг 1. Передача данных в 64-х разрядной системе.

// Передача в регистр одного числа

movq %rbx, %rax

Листинг 2. Передача данных в 32-х разрядной системе.

// Передача в регистр одного числа

movl %ebx, %eax

Если число такого объема передавать не требуется, то мы можем в одном регистре передать несколько меньших чисел. Такой ход можно сделать на обеих архитектурах, но в случае 64-х разрядной архитектуры, объем данных, передаваемых за один такт, будет все равно больше, чем на 32-х разрядной архитектуре.

Листинг 3. Передача нескольких данных в одном регистре (64-х разрядная система).

// Передача в регистр трех чисел

movl %ecx, %eax

shlq $ 32, %rax

movw %dx %ax

shll $ 16, %eax

movw %bx, %ax

Листинг 4. Передача нескольких данных в одном регистре (32-х разрядная система).

// Передача в регистр трех чисел

movw %cx, %ax

5shll $ 16, %eax

movb %dl, %al

shlw $ 8, %ax

movb %bl, %al

Можно заметить, что, несмотря на то, что в обоих примерах было передано три числа в одном регистре, в случае использования 64-х разрядной архитектуры данные числа имеют большую разрядность, чем при использовании 32-х разрядной архитектуры.

Принцип передачи параметров в функции

С введением 64-х разрядной архитектуры был изменен способ передачи параметров в функции. Если, в случае 32-х разрядной архитектуры, параметры можно было передавать либо через стек, либо через регистры, то при использовании 64-х разрядной архитектуры первые четыре параметра (параметры должны быть целочисленными, указатель на класс (объектно-ориентированное программирование) считается целым числом и всегда помещается в регистр RCX) передаются через регистры RCX, RDX, R8, R9, а остальные через стек.

Листинг 5. Передача параметров в функцию в 64-х разрядной системе.

// Вызов функции с пятью аргументами

movq 5, dword ptr [%rsp+0×20] // Передаем пятый аргумент через стек

movq 4, %r9 // Передаем четвертый аргумент

movq 3, %r8 // Передаем третий аргумент

movq 2, %rdx // Передаем второй аргумент

movq 1, %rax // Передаем первый аргумент

call func // Вызываем функцию

func:

// …

// Код функции …

// …

addq 0×20, %rsp // Очищаем стек

ret // Возвращаем управление

Листинг 6. Передача параметров в функцию в 32-х разрядной системе.

// Вызов функции с пятью аргументами

pushl 5

pushl 4

pushl 3

pushl 2

pushl 1

call func

func:

// …

// Код функции …

Ret

Работа со стеком

В 64-разрядной архитектуре один элемент стека является 64-разрядным и меньшее значение туда положить нельзя. Стек выравнивается по границе в 16 Б, а не 8 Б в случае 32-разрядной архитектуры. Все остальные параметры работы со стеком остаются прежними, кроме того, что в 64-х разрядной архитектуре чаще всего применяется парадигма «резервирование пространства и повторное использование его», и именно из-за этого вызываемая функция не занимается чисткой стека. Этим должен заниматься вызывающий. При вызове функции обязательно должны сохраняться все регистры, кроме RAX, RCX, RDX, R8, R9, R10 и R11.

Адресация

программирование процессор архитектура адресация

Смена архитектуры никак не повлияла на смену способа адресации внутри программы. Адресация в 64-х разрядной системе строится по тому же принципу, как и в 32-х разрядной, и команда обращения к адресу занимает одинаковое количество байт и тактов.

Листинг 7. Адресация в 64-х разрядной системе.

// Загрузка опкода следующей машинной команды

movb [%rip], %al

nop

// Абсолютная адресация

xorq %r9, %r9

decb byte ptr (%r9+$ 777h)

Листинг 8. Адресация в 32-х разрядной системе.

// Загрузка опкода следующей машинной команды

call $ + 5

popl %ebx

addl $ 6, %ebx

movb (%ebx), %al

nop

// Абсолютная адресация

decb byte ptr ($ 777h)

3. Листинг программы для сравнения архитектур i686 и amd64

Листинг 9. Простейшая программа шифрования текста для архитектуры amd64..text

.globl crypt

.type crypt, @function

crypt:

.LFB0:

pushq %rbp

movq %rsp, %rbp

subq $ 32, %rsp

movq %rdi, -24(%rbp)

movq %rsi, -32(%rbp)

movl $ 0, -16(%rbp)

movl $ 0, -12(%rbp)

movq -24(%rbp), %rax

movq %rax, %rdi

call strlen

movq %rax, %rdi

call malloc

movq %rax, -8(%rbp)

jmp .L2

.L3:

movl -16(%rbp), %eax

movslq %eax, %rdx

movq -8(%rbp), %rax

addq %rax, %rdx

movl -16(%rbp), %eax

movslq %eax, %rcx

movq -24(%rbp), %rax

addq %rcx, %rax

movzbl (%rax), %ecx

movl -12(%rbp), %eax

movslq %eax, %rsi

movq -32(%rbp), %rax

addq %rsi, %rax

movzbl (%rax), %eax

xorl %ecx, %eax

movb %al, (%rdx)

addl $ 1, -16(%rbp)

addl $ 1, -12(%rbp)

movl -12(%rbp), %eax

movslq %eax, %rdx

movq -32(%rbp), %rax

addq %rdx, %rax

movzbl (%rax), %eax

testb %al, %al

jne .L2

movl $ 0, -12(%rbp)

.L2:

movl -16(%rbp), %eax

movslq %eax, %rdx

movq -24(%rbp), %rax

addq %rdx, %rax

movzbl (%rax), %eax

testb %al, %al

jne .L3

movq -8(%rbp), %rax

leave

ret

8.LFE0:

.size crypt, .-crypt

.section .rodata

.LC0:

.string «Hello, World!»

.LC1:

.string «My_key111»

.LC2:

.string «———————»

.text

.globl main

.type main, @function

main:

.LFB1:

pushq %rbp

movq %rsp, %rbp

subq $ 32, %rsp

movl %edi, -20(%rbp)

movq %rsi, -32(%rbp)

movq $.LC0, -16(%rbp)

movq $.LC1, -8(%rbp)

movq -16(%rbp), %rax

movq %rax, %rdi

call puts

movl $.LC2, %edi

call puts

movq -8(%rbp), %rdx

movq -16(%rbp), %rax

movq %rdx, %rsi

movq %rax, %rdi

call crypt

movq %rax, -16(%rbp)

movq -16(%rbp), %rax

movq %rax, %rdi

call puts

movq -8(%rbp), %rdx

movq -16(%rbp), %rax

movq %rdx, %rsi

movq %rax, %rdi

call crypt

movq %rax, -16(%rbp)

movl $.LC2, %edi

call puts

movq -16(%rbp), %rax

movq %rax, %rdi

call puts

movl $ 0, %eax

leave

ret

.LFE1:

.size main, .-main

Листинг 10. Простейшая программа шифрования текста для архитектуры i686. text

.globl crypt

.type crypt, @function

crypt:

.LFB0:

pushl %ebp

9movl %esp, %ebp

pushl %ebx

subl $ 36, %esp

movl $ 0, -12(%ebp)

movl $ 0, -16(%ebp)

movl 8(%ebp), %eax

movl %eax, (%esp)

call strlen

movl %eax, (%esp)

call malloc

movl %eax, -20(%ebp)

jmp .L2

.L3:

movl -12(%ebp), %edx

movl -20(%ebp), %eax

addl %eax, %edx

movl -12(%ebp), %ecx

movl 8(%ebp), %eax

addl %ecx, %eax

movzbl (%eax), %ecx

movl -16(%ebp), %ebx

movl 12(%ebp), %eax

addl %ebx, %eax

movzbl (%eax), %eax

xorl %ecx, %eax

movb %al, (%edx)

addl $ 1, -12(%ebp)

addl $ 1, -16(%ebp)

movl -16(%ebp), %edx

movl 12(%ebp), %eax

addl %edx, %eax

movzbl (%eax), %eax

testb %al, %al

jne .L2

movl $ 0, -16(%ebp)

.L2:

movl -12(%ebp), %edx

movl 8(%ebp), %eax

addl %edx, %eax

movzbl (%eax), %eax

testb %al, %al

jne .L3

movl -20(%ebp), %eax

addl $ 36, %esp

popl %ebx

popl %ebp

ret

.LFE0:

.size crypt, .-crypt

.section .rodata

.LC0:

.string «Hello, World!»

.LC1:

.string «My_key111»

.LC2:

.string «———————»

.text

.globl main

.type main, @function

main:

10.LFB1:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

subl $ 32, %esp

movl $.LC0, 28(%esp)

movl $.LC1, 24(%esp)

movl 28(%esp), %eax

movl %eax, (%esp)

call puts

movl $.LC2, (%esp)

call puts

movl 24(%esp), %eax

movl %eax, 4(%esp)

movl 28(%esp), %eax

movl %eax, (%esp)

call crypt

movl %eax, 28(%esp)

movl 28(%esp), %eax

movl %eax, (%esp)

call puts

movl 24(%esp), %eax

movl %eax, 4(%esp)

movl 28(%esp), %eax

movl %eax, (%esp)

call crypt

movl %eax, 28(%esp)

movl $.LC2, (%esp)

call puts

movl 28(%esp), %eax

movl %eax, (%esp)

call puts

movl $ 0, %eax

leave

ret

.LFE1:

.size main, .-main

4. Пример работы программы

Рисунок 1. Пример работы простейшей программы шифрования текста на архитектуре amd64.

Рисунок 2. Пример работы простейшей программы шифрования текста на архитектуре i686.

5. Сравнение программ

На таком простом примере сложно заметить прирост производительности «на глаз», но пример с шифрованием и дешифрованием данных был выбран неслучайно.

В большинстве алгоритмов шифрования и дешифрования данных, а также при составлении хэш-сумм требуется использование 64-х или более разрядных данных. Анализируя исходный код в примерах можно заметить, что использование 64-х разрядной архитектуры позволяет за один такт передать большее количество данных, а следовательно увеличить скорость работы алгоритма. При использовании многопоточных программ данный выигрыш будет заметен еще больше.

Вывод

В ходе выполнения данной работы был проведен сравнительный анализ основных отличий программирования на 32-х и 64-х разрядном ассемблерах.

Данный анализ показал, что использование 64-х разрядной архитектуры позволяет выполнять большинство задач быстрее, чем на 32-х разрядной архитектуре, но требует большего количество ресурсов компьютера и переучивания программиста. Стоит заметить, что для небольших математических задач и большинства бытовых возможностей 32-х разрядной архитектуры на данный момент хватает, но на данный момент стоит задуматься о том, чтобы уже делать приоритет на подготовку программистов для 64-х разрядных аппаратных платформ.

1. Ассемблер в Linux для программистов C http://ru.wikibooks.org/wiki/Ассемблер_в_Linux_для_программистов_C

2. Все, что нужно знать, чтобы начать программировать для 64-разрядных версий Windows, http://msdn.microsoft.com/ru-ru/library/dd335933.aspx

3. Архитектура x86−64 под скальпелем ассемблерщика, http://www.insidepro.com/kk/072/072r.shtml

4. Битва технологий: x64 против x86, http://www.platform64.net/x64blog/x64_soft/bitva_tehnologiy_x64_protiv_x86.h tml

5. Сравнение производительности веб-браузеров x86 и x64, http://www.platform64.net/x64blog/x64_soft/sravnenie_proizvoditelnosti_veb_br auzerov_x86_i_x64.html

6. Что лучше установить на ноутбук: Windows x86 или x64, http://www.interface.ru/home.asp?artId=23 789

7. Ассемблер в UNIX (мини-FAQ), http://www.insidepro.com/kk/209r.shtml

8. История соглашений вызова, часть 5: amd64, http://www.transl-gunsmoker.ru/2008/12/5-amd64.html

9. От С к Ассемблеру (gcc assembler), http://www.opennet.ru/base/dev/from_c_to_asm.txt.html

Показать весь текст
Заполнить форму текущей работой