Similar presentations:
Низкоуровневое программирование
1. Вавренюк Александр Борисович к.т.н., доцент кафедры компьютерных систем и технологий (№12) abvavrenyuk@mephi.ru
2. Низкоуровневое программирование
3. Виды занятий
• Лекции• Лабораторные работы
Отчетность:
зачет
4. Лекции
Рассматривается 64-разрядныйвариант архитектуры x86 (x86-64) и
основы языка ассемблера для данной
архитектуры (Intel-синтаксис).
Примеры написания программ.
Еженедельно по 2 часа.
5. Лабораторные работы
• Арифметические операции• Обработка матриц
• Обработка строк
• Работа с библиотеками Си
• Сложные многомодульные задачи
Занятия – раз в неделю с третьей недели.
6. История архитектуры x86 (1)
Первый процессор компании Intel8086 – 8 июня 1978 (16-разрядный),
4 – 16 МГц. 20-разрядная шина адреса.
Модификация 8088 (8-разрядная шина
данных) использовалась в первых
персональных компьютерах IBM PC
(IBM PC/XT) (1981 год) (4,43 МГц).
7. История архитектуры x86 (2)
Intel 80186 – 1982 год (6 – 25 МГц).Расширенный набор команд,
встроенные дополнительные адаптеры,
редко использовался в персональных
компьютерах, чаще в
специализированных
микропроцессорных устройствах.
8. История архитектуры x86 (3)
Intel 80286 (i286) – 1 февраля 1982 (6 –20 МГц). 24-разрядная шина адреса.
Новый режим работы ˗ защищенный.
Дополнительные команды и регистры
для поддержки данного режима.
Виртуальная память до 1 ГБ.
Основа IBM PC/AT (1984 год) 6 МГц.
9. История архитектуры x86 (4)
Intel 80386 (i386) – 17 октября 1985,(32-разрядный), 12 – 40 МГц.
Увеличенный буфер предвыборки
команд. Все регистры 32-разрядные.
Расширенная система команд не
только для поддержки разрядности.
10. История архитектуры x86 (5)
Intel 80386 (i386).Страничная организация памяти. (4Кб)
4Гб физической памяти и 64 Гб
виртуальной памяти.
Режим виртуального 8086.
Основа IBM PC 386 и IBM PS/2-80.
11. История архитектуры x86 (6)
Intel 80486 (i486) – 10 апреля 1989, (32разрядный), 12 – 150 МГц.64 Tб виртуальной памяти.
Встроенный математический
сопроцессор и контроллер кэша.
Дополнительные команды. Основа
портативных ноутбуков.
12. История архитектуры x86 (7)
Pentium, Pentium MMX (i586) – 22марта 1993, январь 1997 до 4ГГц.
Суперскалярный, суперконвейерный.
Pentium Pro, Pentium II (i686) – 1995,
1997 год.
Pentium III (SSE), Pentium M,
Pentium 4. (1999 – 2003)
13. История архитектуры x86 (8)
Создание 64-разрядной версии(компания AMD) 2000 год.
Обратная совместимость с x86.
AMD с 2001 года поддерживает x86-64
в многих своих процессорах: Athlon64,
Phenom, Turion64.
14. История архитектуры x86 (9)
Intel поддерживает с 2003 года x86-64в своих процессорах: Celeron, Pentium,
Core, Xeon.
Все 64-разрядные процессоры (AMD,
Intel) поддерживают для обратной
совместимости 32-разрядный режим
со всеми особенностями (реальный,
защищенный, виртуального 8086).
15. Архитектура x86-64 (1)
Адрес 64-разрядный, реальноиспользуются 48 разрядов, что
позволяет адресовать 256 ТБ.
16. Архитектура x86-64 (2)
Два диапазона адресов:пользовательский
0x0000000000000000 –
0x00007FFFFFFFFFFF,
системный
0xFFFF800000000000 –
0xFFFFFFFFFFFFFFFF.
17. Регистры x86-64 (1)
64-разрядныеrip – счетчик команд
rsp – указатель стека
rax – аккумулятор
rbx – база
rcx – счетчик
rdx – регистр данных
18. Регистры x86-64 (2)
64-разрядныеrsi – индекс источника
rdi – индекс приемника
rbp – указатель базы
r8 – r15 – восемь дополнительных
регистров.
Все регистры, кроме rip, еще
называются регистрами общего
назначения (РОН).
19. Регистры x86-64 (3)
Все регистры общего назначенияподдерживают доступ к своей
младшей половине (двойное слово),
младшей четверти (слово), младшей
восьмой части (байт).
20. Регистры x86-64 (4)
Наименование частей РОН:rax -> eax -> ax -> al
rbx -> ebx -> bx -> bl
rcx -> ecx -> cx -> cl
rdx -> edx -> dx -> dl
rdi -> edi -> di -> dil
rsi -> esi -> si -> sil
rbp -> ebp -> bp -> bpl
rsp -> esp -> sp -> spl
21. Регистры x86-64 (5)
r8 -> r8d -> r8w -> r8br9 -> r9d -> r9w -> r9b
r10 -> r10d -> r10w -> r10b
r11 -> r11d -> r11w -> r11b
r12 -> r12d -> r12w -> r12b
r13 -> r13d -> r13w -> r13b
r14 -> r14d -> r14w -> r14b
r15 -> r15d -> r15w -> r15b
22. Флаги
CF – флаг переносаPF – флаг четности
AF – флаг полупереноса
ZF – флаг нуля
SF – флаг знака
DF – флаг направления
OF – флаг переполнения
23. Способы адресации (1)
Определение, где находятся операндыкоманды
Неявно
Одноадресные команды
Двухадресные команды (только один
операнд может являться ячейкой
оперативной памяти)
24. Способы адресации (2)
Регистровая адресация:mov eax, ebx
Непосредственная адресация:
mov cx, 5
mov rdx, a
a – метка данных
25. Способы адресации (3)
Адресация к памяти: только один из двухоперандов может быть ячейкой памяти.
Базовая адресация:
размер [РОН]
Базовая адресация со смещением:
размер [РОН + смещение]
размер – byte | word | dword | qword
26. Способы адресации (4)
Адресация к памяти: только один из двухоперандов может быть ячейкой памяти.
Индексная адресация:
размер [РОН * 1|2|4|8]
Индексная адресация со смещением:
размер [РОН * 1|2|4|8 + смещение]
размер – byte | word | dword | qword
27. Способы адресации (5)
Адресация к памяти: только один из двухоперандов может быть ячейкой памяти.
Общий вид:
размер [РОН + РОН * 1|2|4|8 + смещение]
размер – byte | word | dword | qword
Адрес может включать не все
компоненты.
28. Способы адресации (6)
Примеры:mov byte [rax+rbx+5], dl
mov cx, word [rbp+rdi*2+8]
mov byte [rbx*4+0x5454], 10
mov dword [rcx], 25
mov ax, word [rsi*2-10]
29. Данные (1)
Константы десятичные:10, 12, -5
двоичные:
01010101b, 1001010010010010b
восьмеричные:
153177q, 1422q
шестнадцатеричные:
0af34h, 0x63ff4312
30. Данные (2)
Константы символьные:от 1 до 4 символов
'a', '"', 'abc', "1234"
mov al, '0'
mov ebx, "0123" ; mov ebx, 0x33323130
31. Данные (3)
Константы строковые:длиннее или при использовании
оператора определения данных
'abcde', 'Hello, world!', "123'456"
a db "Hello"
b db '123'
32. Данные (4)
Определение константы:a equ 12
b equ 'abc'
c equ $-_start
переопределение не допускается,
выражение должно быть вычислимо
при первом проходе.
33. Данные (5)
Определение инициализированныхданных:
db, dw, dd, dq
mas db 1, 2, 3, 4, 5
mesg db 'Hello, world!'
err db 'e', 'r', 'r', 'o', 'r'
a dw 1234h
b dq 0xff00ff00ff00ff00
34. Данные (6)
a db 1, 2, 3, 4b dd 0x01020304
mov ebx, "0123" ; mov ebx, 0x33323130
mov ecx, dword[a] ; ecx=0x04030201
mov edx, dword[b] ; edx=0x01020304
35. Данные (7)
Определение неинициализированныхданных (резервирование):
resb, resw, resd, resq
a resb 200
b resw 100
c resd 10
d resq 1000
36. Команды (1)
Если в качестве приемника вдвухадресной команде или в качестве
операнда в одноадресной команде
используется 32-разрядный регистр, то
старшая часть соответствующего 64разрядного регистра обнуляется.
37. Команды (2)
Пересылка данных:mov op1, op2
Обмен данных:
хchg op1, op2 (нет непосредственной
адресации)
Обмен байтов в 64- или 32-разрядном
регистре:
bswap op
38. Команды (3)
Конвертирование данныхcbw (al –> ax)
cwd (ax –> dx:ax)
cwde (ax –> eax)
cdq (eax –> edx:eax)
cdqe (eax –> rax)
cqo (rax –> rdx:rax)
39. Команды (4)
Конвертирование данныхРасширение нулем
movzx op1, op2
op2 – только 8- или 16-разрядный
операнд.
40. Команды (5)
Конвертирование данныхРасширение знаком
movsx op1, op2
В командах movsz и movsx только
второй операнд может быть ячейкой
памяти.
41. Команды (6)
Вычисление смещения операнда:lea op1, op2
Второй операнд – ячейка памяти. Ее
64-разрядный адрес помещается в
регистр op1.
42. Работа со стеком (1)
Поместить значение в стек:push op
Извлечь значение из стека:
pop op
RSP всегда указывает на вершину
стека (последнее записанное в стек
значение), стек растет в сторону
уменьшения адреса.
43. Работа со стеком (2)
В стек можно помещать только 64разрядные операнды. Значениерегистра RSP должно быть кратно 8.
Говорят, что стек выровнен на границу
64-разрядного слова.
Непосредственное значение
использовать нельзя.
44. Арифметические команды (1)
Арифметические командыустанавливают соответствующие
флаги: OF, SF, ZF, AF, CF, PF.
При выполнении команды разницы
между знаковыми и беззнаковыми
операндами нет. Разницу видит
программист, анализируя
соответствующие флаги.
45. Арифметические команды (2)
CF – используется для анализарезультата беззнаковой операции
(перенос).
SF, OF – используются для анализа
результата знаковой операции (знак,
переполнение).
ZF – используются для анализа
результата любой операции (нуль).
46. Арифметические команды (3)
Сложение:add op1, op2
Вычитание:
sub op1, op2
Сложение с обменом:
xadd op1, op2 (только первый операнд
может быть ячейкой памяти)
47. Арифметические команды (4)
add cl, blcl = 00000101b (5)
bl = 10001000b (136 или -120)
Результат 10001101b (141 или -115)
CF и OF сброшены, SF установлен
Знаковый: 5 + (-120) = -115 верно
Беззнаковый: 5 + 136 = 141 верно
48. Арифметические команды (5)
add cl, blcl = 10000001b (129 или -127)
bl = 10000111b (135 или -121)
Результат 00001000b (8)
CF и OF установлены, SF сброшен
Знаковый: -127 + (-121) = 8 неверно
Беззнаковый: 129 + 135 = 8 неверно
49. Арифметические команды (6)
add cl, blcl = 00000101b (5)
bl = 11111111b (255 или -1)
Результат 00000100b (4)
SF и OF сброшены, CF установлен
Знаковый: 5 + (-1) = 4 верно
Беззнаковый: 5 + 255 = 4 неверно
50. Арифметические команды (7)
add cl, blcl = 01100100b (100)
bl = 01100100b (100)
Результат 11001000b (200 или -56)
SF и OF установлены, CF сброшен
Знаковый: 100 + 100 = -56 неверно
Беззнаковый: 100 + 100 = 200 верно
51. Арифметические команды (8)
sub cl, blcl = 11001000b (200 или -56)
bl = 10100000b (160 или -96)
Результат 00101000b (40)
CF, SF и OF сброшены
Знаковый: -56 - (-96) = 40 верно
Беззнаковый: 200 - 160 = 40 верно
52. Арифметические команды (9)
sub cl, blcl = 01100100b (100)
bl = 11001000b (200 или -56)
Результат 10011100b (156 или -100)
CF, SF и OF установлены
Знаковый: 100 - (-56) = -100 неверно
Беззнаковый: 100 - 200 = 156 неверно
53. Арифметические команды (10)
sub cl, blcl = 11111110b (254 или -2)
bl = 11111111b (255 или -1)
Результат 11111111b (255 или -1)
CF и SF установлены, OF сброшен
Знаковый: -2 - (-1) = -1 верно
Беззнаковый: 254 - 255 = 255 неверно
54. Арифметические команды (11)
sub cl, blcl = 10000000b (128 или -128)
bl = 01100100b (100)
Результат 00011100b (28)
OF установлен, CF и SF сброшены
Знаковый: -128 - 100 = 28 неверно
Беззнаковый: 128 - 100 = 28 верно
55. Арифметические команды (12)
Сложение c переносом:adc op1, op2
Вычитание с займом:
sbb op1, op2
56. Арифметические команды (13)
add rax, rcxadc rbx, rdx
sub rax, rcx
sbb rbx, rdx
57. Арифметические команды (14)
Увеличение операнда на единицу:inc op (не влияет на флаг CF)
Уменьшение операнда на единицу:
dec op (не влияет на флаг CF)
Изменение знака числа:
neg op (если операнд – нуль, то CF
сбрасывается, иначе устанавливается)
58. Умножение и деление (1)
Беззнаковое умножение:mul op (нет непосредственной
адресации)
al * op –> ax
ax * op –> dx:ax
eax * op –> edx:eax
rax * op -> rdx:rax
59. Умножение и деление (2)
Знаковое умножение:imul op (нет непосредственной
адресации)
al * op –> ax
ax * op –> dx:ax
eax * op –> edx:eax
rax * op -> rdx:rax
60. Умножение и деление (3)
Знаковое умножение:imul op1, op2 (только второй операнд
может быть ячейкой памяти)
imul op1, op2, op3 (только op2 может
быть ячейкой памяти, op2 – не может
быть непосредственным операндом,
op3 – непосредственный операнд)
61. Умножение и деление (4)
Знаковое деление:idiv op
Беззнаковое деление:
div op
Нет непосредственной адресации.
62. Умножение и деление (5)
Деление (знаковое и беззнаковое):ax / op –> al, остаток в ah
dx:ax / op –> ax, остаток в dx
edx:eax / op –> eax, остаток в edx
rdx:rax / op –> rax, остаток в rdx
63. Логические команды (1)
Логическое «И»:and op1, op2
Логическое «ИЛИ»:
or op1, op2
Логическое исключающее «ИЛИ»:
хor op1, op2
Инверсия:
not op
64. Логические команды (2)
Влияние логических команд на флаги.Флаги CF и OF сбрасываются, а SF, ZF
и PF устанавливаются в соответствии с
результатом. AF не определен.
Команда not на флаги не влияет.
65. Логические команды (3)
and cl, blcl = 01010101b (85)
bl = 01000110b (70)
Результат 01000100b (68) в cl
SF, ZF сброшены, PF установлен
OF и CF сброшены, AF не определен
66. Логические команды (4)
or cl, blcl = 01010101b (85)
bl = 01000110b (70)
Результат 01010111b (87) в cl
SF, PF и ZF сброшены
OF и CF сброшены, AF не определен
67. Логические команды (5)
хor cl, blcl = 01010101b (85)
bl = 01000110b (70)
Результат 00010011b (19) в cl
SF, PF и ZF сброшены
OF и CF сброшены, AF не определен
68. Логические команды (6)
not clcl = 01010101b (85)
Результат 10101010b (170 или -86) в cl
Флаги не определены.
69. Команды сдвига (1)
Арифметические сдвиги:sar/sal op1, op2
Логические сдвиги:
shr/shl op1, op2
(op2 – непосредственный операнд или
cl)
CF содержит выдвигаемый бит
OF определен только при сдвиге на 1
70. Команды сдвига (2)
SHR0
CF
7, 15, 31, 63
0
SAR
CF
7, 15, 31, 63
SAL/SHL
0
CF
0
7, 15, 31, 63
0
71. Команды сдвига (3)
Циклические сдвиги:ror/rol op1, op2
Циклические сдвиги через CF:
rcr/rcl op1, op2
(op2 – непосредственный операнд или
cl)
CF содержит выдвигаемый бит
OF определен только при сдвиге на 1
72. Команды сдвига (4)
RORCF
7, 15, 31, 63
ROL
0
CF
7, 15, 31, 63
0
RCR
CF
7, 15, 31, 63
RCL
0
CF
7, 15, 31, 63
0
73. Команды сдвига (5)
Сдвиги повышенной точности:shrd/shld op1, op2, op3
(только op1 может быть ячейкой
памяти, op3 – непосредственный
операнд или cl)
CF содержит выдвигаемый бит
OF определен только при сдвиге на 1
74. Команды сдвига (6)
SHRDисточник
15, 31, 63
приемник
0
15, 31, 63
CF
0
SHLD
приемник
CF
15, 31, 63
источник
0
15, 31, 63
0
75. Битовые команды (1)
Проверка бита:bt op1, op2
op1 – обычный операнд (битовая база)
op2 – число не больше 16|32|64 или
регистр (битовое смещение)
Указанный бит считывается в CF.
76. Битовые команды (2)
Проверка и модификация бита:bts op1, op2 – установка бита
btr op1, op2 – сброс бита
btc op1, op2 – инверсия бита
op1 – битовая база
op2 – битовое смещение
Старое значение бита считывается в
CF.
77. Битовые команды (3)
Поиск первой единицы в битовойстроке:
bsf op1, op2 – поиск с младшего бита
bsr op1, op2 – поиск со старшего бита
op1 – регистр (номер бита)
op2 – обычный операнд
Если операнд равен нулю, то результат
не определен и ZF устанавливается.
78. Безусловный переход (1)
Метка – символьное обозначениеадреса некоторой команды.
m1: add ax, bx
m2: sub bl, dl
В командах перехода операндом
является метка, которую ассемблер
заменяет смещением соответствующей
команды.
79. Безусловный переход (2)
jmp met1При использовании метки ассемблер
автоматически использует либо
короткое смещение (-128 – 127), либо
длинное (-231 – 231-1).
80. Безусловный переход (2)
jmp rbxjmp qword [rbx+rsi]
При использовании регистровой
адресации или памяти всегда переход
на абсолютный 64-разрядный адрес.
81. Условный переход
Условие зависит от флагов.Флаги устанавливают обычные
команды и специальные команды.
jcc метка
При использовании метки ассемблер
автоматически использует либо
короткое смещение (-128 – 127), либо
длинное (-231 – 231-1).
82. Работа с флагами (1)
Арифметическое сравнение:cmp op1, op2
(Фактически sub op1, op2, но результат
никуда не записывается).
Логическое сравнение:
test op1, op2
(Фактически and op1, op2, но результат
никуда не записывается).
83. Работа с флагами (2)
Установить флаг переноса:stc
Сбросить флаг переноса:
clc
Инвертировать флаг переноса:
cmc
84. Условия (1)
Для команды jcc (вместо ccподставляются соответствующие
символы)
Равенство/неравенство
Если равно (если ноль)
e или z (ZF = 1)
Если не равно (если не ноль)
ne или nz (ZF = 0)
85. Условия (2)
Если нет переполненияno (OF = 0)
Если есть переполнения
o (OF = 1)
Если нет знака
ns (SF = 0)
Если есть знак
s (SF = 1)
86. Условия (3)
Если нет четности (если нечетное)np po (PF = 0)
Если есть четность (если четное)
p pe (PF = 1)
87. Условия (4)
Знаковые условияЕсли больше (если не меньше и не
равно)
g или nle (ZF = 0 и SF = OF)
Если не больше (если меньше или
равно)
ng или le (ZF = 1 или SF <> OF)
88. Условия (5)
Знаковые условияЕсли меньше (если не больше и не
равно)
l или nge (SF <> OF)
Если не меньше (если больше или
равно)
nl или ge (SF = OF)
89. Условия (6)
Беззнаковые условияЕсли выше (если не ниже и не равно)
a или nbe (CF = 0 и ZF = 0)
Если не выше (если ниже или равно)
na или be (CF = 1 или ZF = 1)
90. Условия (7)
Беззнаковые условияЕсли ниже (если не выше и не равно)
Если перенос
b или nae или c (CF = 1)
Если не ниже (если выше или равно)
Если нет переноса
nb или ae или nc (CF = 0)
91. Записать условие в байт
setcc op(операнд имеет размер 1 байт)
cc – условия как в команде jcc
Записывается либо 0 – ложь, либо 1 –
истина.
92. Организация циклов (1)
Счетчик цикла – регистр rcx.Работает на вычитание.
Если до начала цикла регистр равен
нулю, то максимальное число итераций
18446744073709551616.
93. Организация циклов (2)
Циклloop метка
Цикл пока равно (пока ноль)
loope (loopz) метка
Цикл пока не равно (пока не ноль)
loopne (loopnz) метка
Переходы только в диапазоне -128 –
127.
94. Организация циклов (3)
Переход если ecx | rcx=0jecxz | jrcxz метка
Переход только в диапазоне -128 – 127.
95. Условные пересылки
Условная пересылка:cmovcc op1, op2
сс – в конце команды условия,
аналогичные команде условного
перехода. Пересылка происходит
только в случае истинности условия.
В команде только второй операнд
может быть ячейкой памяти. В команде
нет непосредственных значений.
96. Цепочечные команды (1)
Группа команд с неявными двумяоперандами типа «память» «память» и
«регистр al/ax/eax/rax» «память».
Удобно обрабатывать массивы,
матрицы и строки.
Учитывают флаг направления DF.
97. Цепочечные команды (2)
Сбросить флаг направления:cld
Команды работают в сторону
увеличения адресов.
Установить флаг направления:
std
Команды работают в сторону
уменьшения адресов.
98. Цепочечные команды (3)
Копирование байтов/слов/двойныхслов/учетверенных слов
movsb/movsw/movsd/movsq
[rsi] -> [rdi]
После выполнения команды rsi и rdi
увеличиваются (уменьшаются,
определяется по соcтоянию DF) на
1|2|4|8.
99. Цепочечные команды (4)
Загрузка байта/слова/двойногослова/учетверенного слова
lodsb/lodsw/lodsd/lodsq
[rsi] -> al|ax|eax|rax
После выполнения команды rsi
увеличивается (уменьшается,
определяется по соcтоянию DF) на
1|2|4|8.
100. Цепочечные команды (5)
Сохранение байта/слова/двойногослова/учетверенного слова
stosb/stosw/stosd/stosq
al|ax|eax|rax -> [rdi]
После выполнения команды rdi
увеличивается (уменьшается,
определяется по соcтоянию DF) на
1|2|4|8.
101. Цепочечные команды (6)
Префикс повторения rep перед любой изкоманд movs, lods, stos позволяет
повторять команды столько раз, сколько
записано в регистре rcx.
Например, скопировать строку
<следующий слайд>
102. Цепочечные команды (6)
mov rsi, src ; адрес исходной строкиmov rdi, dst ; адрес результата
cld ; движение вперед
mov rcx, len ; длина строки
rep movsb ; копирование len раз
103. Цепочечные команды (7)
Сравнение байтов/слов/двойныхслов/учетверенных слов
cmpsb/cmpsw/cmpsd/cmpsq
[rsi] - [rdi] (без сохранения результата,
влияет на флаги: AF, CF, SF, OF, PF, ZF)
После выполнения команды rsi и rdi
увеличиваются (уменьшаются,
определяется по соcтоянию DF) на
1|2|4|8.
104. Цепочечные команды (8)
Сканирование байта/слова/двойногослова/учетверенного слова
scasb/scasw/scasd/scasq
al|ax|eax|rax - [rdi] (без сохранения
результата, влияет на флаги: AF, CF, SF, OF,
PF, ZF)
После выполнения команды rdi
увеличивается (уменьшается, определяется
по соcтоянию DF) на 1|2|4|8.
105. Цепочечные команды (9)
Префикс повторения repe/repne передлюбой из команд cmps, scas позволяет
повторять команды пока равно/пока не
равно, но не более количества раз,
записанного в регистре rcx.
Например, сравнить две строки:
<следующий слайд>
106. Цепочечные команды (10)
mov rsi, src ; адрес первой строкиmov rdi, dst ; адрес второй строки
cld ; движение вперед
mov rcx, len ; длина строки
repe cmpsb ; сравнение len раз
je <строки равны>
<строки не равны>
107. Цепочечные команды (11)
Например, найти первое вхождениесимвола в строку:
<следующий слайд>
108. Цепочечные команды (12)
mov rdi, dst ; адрес строкиmov al, c ; искомый символ
cld ; движение вперед
mov rcx, len ; длина строки
repne scasb ; сравнение len раз
je <символ найден> ([rdi-1])
<символ не найден>
109. Вызов процедур (1)
Вызов процедуры:call метка
call op
call qword [op]
При использовании метки ассемблер
использует длинное (-231 – 231-1)
относительное смещение.
110. Вызов процедур (2)
op – 64-разрядный РОН, содержащийадрес начала процедуры.
qword [op] – любая допустимая ссылка
на ячейку памяти.
Примеры:
call proc7
call rcx
call qword [rax+rbx+10]
111. Вызов процедур (3)
При вызове процедуры адресследующей команды автоматически
сохраняется в стеке.
Возврат из процедуры:
ret
Происходит возврат из процедуры по
адресу команды, следующей за
командой вызова процедуры и
сохраненной стеке.
112. Соглашения вызовов (1)
Для успешной связи ассемблерныхпроцедур с процедурами,
написанными на других языках (в
частности на Си) требуется соблюдать
соглашения. Вызов из программы на
Си ассемблерных процедур или вызов
из ассемблерных программ, функций
написанных на языке Си.
113. Соглашения вызовов (2)
Передача параметров, если ихколичество не превышает шесть,
осуществляется через регистры rdi, rsi,
rdx, rcx, r8, r9. Зависит от размера
соответствующих типов данных.
(Структуры больших размеров и
параметры с плавающей точкой
передаются по-другому). Остальные
параметры передаются через стек.
114. Соглашения вызовов (3)
Процедура возвращает значение черезрегистр rax (в зависимости от
размера). (Структуры больших
размеров и параметры с плавающей
точкой передаются по-другому).
115. Соглашения вызовов (4)
Вызывающая программа не должнанадеяться на сохранение значений во
всех регистрах, кроме rbx, rbp, r12, r13,
r14, r15. Следовательно, если
процедура будет использовать эти
регистры, то она обязана сохранить
значения этих регистров в стеке, а
перед возвратом восстановить их.
116. Соглашения вызовов (5)
Если вызывающая программапользуется регистрами, которые
вызываемая процедура сохранять не
должна, то вызывающая программа
сохраняет данные регистры в стеке
или в стековом кадре, а после возврата
управления восстанавливает их.
117. Соглашения вызовов (6)
Если процедура планируетиспользовать локальные переменные
или вызывать другие процедуры, то
она создает стековый кадр (фрейм), и
записывает указатель на стековый кадр
в регистр rbp. (Любая процедура,
использующая rbp, обязана
восстанавливать значение перед
возвратом.)
118. Соглашения вызовов (7)
Вход в процедуру:push rbp
mov rbp, rsp
sub rsp, <размер стекового кадра>
Сохранение регистров, которые
процедура будет использовать, но
обязана сохранять в соответствии с
соглашением о вызовах.
119. Соглашения вызовов (8)
Выход из процедуры:Восстановление регистров.
leave
ret
Команда leave заменяет две команды:
mov rsp, rbp
pop rbp
120. Соглашения вызовов (9)
Если весь код написан однимпрограммистом на языке ассемблера,
то использование соглашения о
вызовах не обязательно. Но если
планируетcя писать процедуры,
вызываемые из кода на языке Си или
наоборот вызывать функции Си, то для
корректной работы следует строго
придерживаться соглашения о
вызовах.
121. Передача параметров от ОС (1)
При запуске программа от ОСполучает через стек следующие
параметры (все размером
учетверенное слово):
количество параметров командной
строки,
122. Передача параметров от ОС (2)
параметры командной строки (в видеуказателей на строки,
заканчивающиеся нулевым байтом),
нулевое значение, переменные
окружения (в виде указателей на
строки, заканчивающиеся нулевым
байтом), нулевое значение.
123. Передача параметров от ОС (3)
Имя запускаемой программы всегдапередается в качестве первого
параметра. Таким образом, при запуске
без параметров программа будет
иметь: количество параметров – 1, имя
программы, нулевое значение, далее
переменные окружения, нулевое
значение.
124. Передача параметров от ОС (4)
При запуске:prog t1 12 text
Состояние стека:
[rsp] = 4 количество параметров,
включая имя программы,
[rsp+8] = адрес строки «prog»,
[rsp+16] = адрес строки «t1»,
125. Передача параметров от ОС (5)
[rsp+24] = адрес строки «12»,[rsp+32] = адрес строки «text»,
[rsp+40] = 0,
[rsp+48] = адрес первой переменной
окружения,
[rsp+56] = адрес второй переменной
окружения и т.д.
126. Системные вызовы (1)
Обращение к ОС для выполнениякакой-либо сервисной функции носит
название системный вызов. (Открыть
файл, прочитать, записать…). В
архитектуре x64 системные вызовы
осуществляются через команду syscall.
127. Системные вызовы (2)
Параметры системного вызовапередаются через регистры rdi, rsi, rdx,
r10, r8, r9 а номер системного вызова –
через регистр rax. Системный вызов
возвращает результат через регистр
rax. Отрицательное значение
соответствует ошибке. Системный
вызов не гарантирует сохранение
регистров rax, rcx, r11.
128. Системные вызовы (3)
Полный список системных вызовов x86_64Linux можно посмотреть:
https://syscalls.mebeim.net/?table=x86/64/x64
129. Системные вызовы (4)
Коды ошибок:1 – Operation not permitted
2 – No such file or directory
5 – Input/output error
6 – No such device or address
7 – Argument list too long
9 – Bad file descriptor
11 – Resource temporarily unavailable
130. Системные вызовы (5)
Коды ошибок:12 – Cannot allocate memory
13 – Permission denied
14 – Bad address
17 – File exists
20 – Not a directory
21 – Is a directory
22 – Invalid argument
131. Системные вызовы (6)
Коды ошибок:23 – Too many open files in system
24 – Too many open files
27 – File too large
28 – No space left on device
29 – Illegal seek
36 – File name too long
39 – Directory not empty
132. Системные вызовы (7)
Если в качестве параметра всистемный вызов передается строка
символов, то она должна быть
завершена нулевым байтом.
Параметры – целые числа (флаги)
передаются через 32-х разрядные
регистры.
Указатели, в том числе адреса строк,
передаются через 64-х разрядные
регистры.
133. Системные вызовы (8)
Файл или каталог задаютсяабсолютным (относительно корневого
каталога) либо относительным
(относительно текущего каталога)
путем. Если первый символ пути ‘/’, то
подразумевается абсолютный путь,
иначе – относительный путь. Если
указано, что требуется имя файла или
каталога – нужно указать абсолютный
или относительный путь.
134. Системные вызовы (9)
Получение текущего каталога:rax – 79
rdi – адрес буфера для записи
абсолютного пути к текущему
каталогу
rsi – размер буфера
Возврат:
rax – размер строки, включая нулевой
байт в конце.
135. Системные вызовы (10)
Изменение текущего каталога:rax – 80
rdi – адрес буфера с именем каталога
Возврат:
rax – 0.
136. Системные вызовы (11)
Создание каталога:rax – 83
rdi – адрес буфера с именем нового
каталога
rsi – права доступа к новому каталогу
Возврат:
rax – 0.
137. Системные вызовы (12)
Удаление пустого каталога:rax – 84
rdi – адрес буфера с именем
удаляемого каталога
Возврат:
rax – 0.
138. Системные вызовы (13)
Открытие файла:rax – 2
rdi – адрес буфера с именем файла
rsi – флаги
rdx – права доступа
Возврат:
rax – файловый дескриптор.
139. Системные вызовы (14)
Открытие файла:Вызов возвращает файловый
дескриптор, который должен
использоваться во всех дальнейших
операциях с файлом. Указатель в
файле установлен на начало файла.
140. Системные вызовы (15)
Флаги при открытии файла:Обязательные:
0 – только чтение
1 – только запись
2 – чтение и запись
141. Системные вызовы (16)
Флаги при открытии файла:Дополнительные:
0x40 – при необходимости создать
файл
0xc0 – обязательно создать файл, если
файл уже существует, то ошибка
0x200 – очистить содержимое файла
0x400 – запись возможна только в
конец файла
142. Системные вызовы (17)
Права доступа при открытии файла:Параметр игнорируется, если файл
уже существует. Если создается новый
файл (заданы соответствующие
флаги), то задает права в виде
rwxrwxrwx (права для создателя,
группы и остальных пользователей) c
коррекцией по маске.
143. Системные вызовы (18)
Стандартные файловые дескрипторы:0 – стандартный ввод, связан с
клавиатурой
1 – стандартный вывод, связан с
экраном
2 – стандартный протокол, связан с
экраном
144. Системные вызовы (19)
Создание файла:rax – 85
rdi – адрес буфера с именем файла
rsi – права доступа
Возврат:
rax – файловый дескриптор.
145. Системные вызовы (20)
Создание файла:Вызов аналогичен открытию файла с
флагами: «только запись», «при
необходимости создать файл»,
«очистить содержимое файла».
146. Системные вызовы (21)
Чтение из файла:rax – 0
rdi – файловый дескриптор
rsi – адрес буфера, куда будет
происходить чтение
rdx – размер буфера
Возврат:
rax – количество прочитанных байтов.
147. Системные вызовы (22)
Чтение из файла:Количество прочитанных байтов
может быть меньше размера буфера,
если достигнут конец файла. Указатель
в файле автоматически смещается на
количество прочитанных байтов.
Количество прочитанных байтов
может быть равно нулю. Это означает,
что указатель в файле уже находится в
конце файла.
148. Системные вызовы (23)
Запись в файл:rax – 1
rdi – файловый дескриптор
rsi – адрес буфера, откуда будет
происходить запись
rdx – размер буфера
Возврат:
rax – количество записанных байтов.
149. Системные вызовы (24)
Запись в файл:Указатель в файле автоматически
смещается на количество записанных
байтов. Если при открытии файла
установлен флаг 0x200 (запись
возможна только в конец файла), то
перед операцией записи указатель в
файле смещается в конец файла.
150. Системные вызовы (25)
Позиционирование указателя в файле:rax – 8
rdi – файловый дескриптор
rsi – смещение в файле
rdx – флаги
Возврат:
rax – новое значение указателя в
файле.
Нумерация начинается с нуля.
151. Системные вызовы (26)
Флаги для позиционированияуказателя в файле:
0 – смещение задано относительно
начала файла
1 – смещение задано относительно
текущей позиции в файле
2 – смещение задано относительно
конца файла
152. Системные вызовы (27)
Закрытие файла:rax – 3
rdi – файловый дескриптор
Возврат:
rax – 0.
153. Системные вызовы (28)
Удаление файла:rax – 87
rdi – адрес буфера с именем файла
Возврат:
rax – 0.
154. Системные вызовы (29)
Завершение программы:rax – 60
rdi – код завершения в диапазоне (0 –
255) (т.е. содержимое dil)
Происходит передача управления ОС.
Считается, что обычно программа
возвращает 0, а любое другое значение
соответствует коду ошибки.
155. Вещественные числа (1)
Используются для представленияфизических величин. Могут быть
представлены только с некоторой
точностью. Обычно стремятся
независимо от абсолютного значения
обеспечить фиксированную
относительную погрешность. Таким
свойством обладает экспоненциальная
форма представления вещественного
числа.
156. Вещественные числа (2)
Число состоит из мантиссы и порядка.В десятичном представлении порядок
– степень числа десять.
Примеры:
2,345 * 107
-1,281 * 10-3
3,767 * 100
Знак мантиссы – знак числа.
157. Вещественные числа (3)
Если жестко задать диапазонпредставления мантисс, например
мантисса обязательно больше или
равна 1 и строго меньше 10, то любое
число имеет однозначное
представление. А если ограничить в
мантиссе число значащих цифр, то
получим строго заданный диапазон
относительных погрешностей
представления.
158. Вещественные числа (4)
Также ограничим диапазон порядков иполучим минимально представимое
число и максимально представимое
число. (По модулю). Например:
количество значащих цифр мантиссы
5, диапазон порядков ±100.
Максимальное число: 9,9999 * 10100
Минимальное (по модулю) число:
1,0000 * 10-100
159. Вещественные числа (5)
Процессору удобнее оперировать сдвоичными числами: мантисса –
двоичное число, порядок степень
числа 2. Можно также задать диапазон
представления мантисс, например
больше одного и строго меньше 2 (10).
Тогда любое число будет иметь
однозначное представление в этой
форме. Аналогично можно ограничить
разрядность мантиссы и порядка.
160. Вещественные числа (6)
Зададим количество значащих цифр 5и диапазон порядков ±7 (±111).
Получим максимальное число:
1,1111 * 2111 = 2,4800 * 102
и минимальное (по модулю число):
1,0000 * 2-111 = 1,5137 * 10-2
161. Вещественные числа (7)
Заметим, что любое двоичноевещественное число при отсутствии
ограничений на разрядную сетку
может быть представлено в
десятичном виде. А вот обратное
неверно: не всякое десятичное число с
конечным числом знаков можно
представить в двоичном виде.
0,110 = 0,0001100110011…2
162. Представления (1)
Ограниченность разрядной сеткинакладывает ограничения на
представление вещественных чисел в
компьютере. (Ограничивается
разрядность мантиссы и разрядность
порядка, выделяется один бит под знак
числа). Для представления
вещественных чисел используется
стандарт IEEE 754-2008.
163. Представления (2)
Стандарт определяет числаполовинной, одинарной, двойной и
учетверенной точности. Во всех
стандартах определяется количество
бит, выделяемых под мантиссу и
порядок. Мантисса в диапазоне
(нестрого) от 1 до (строго) 2. Мантисса
всегда начинается с единичного бита,
который можно не хранить.
164. Представления (3)
Таким образом, в представлениихранится только дробная часть
мантисcы. Порядок хранится в
смещенном виде: минимальное (0) и
максимальное (1…1) используются для
специальных чисел, а остальные
значения представляют собой порядок,
из которого вычтено смещение. Один
бит выделяется под знак числа.
165. Половинная точность
Число занимает 16 бит: мантисса (0 –9), порядок (10 – 14), знак (15).
Порядок имеет смещение 15.
Минимальный порядок -14 (00001),
нулевой порядок (01111),
максимальный порядок 15 (11110).
Точность: три десятичных знака.
Десятичный диапазон: 10-4 – 105.
166. Одинарная точность
Число занимает 32 бита: мантисса (0 –22), порядок (23 – 30), знак (31).
Порядок имеет смещение 127.
Минимальный порядок -126
(00000001), нулевой порядок
(01111111), максимальный порядок 127
(11111110).
Точность: 6 – 7 десятичных знаков.
Десятичный диапазон: 10-38 – 1038.
167. Двойная точность
Число занимает 64 бита: мантисса (0 –51), порядок (52 – 62), знак (63).
Порядок имеет смещение 1023.
Минимальный порядок -1022
(00000000001), нулевой порядок
(01111111111), максимальный порядок
1023 (11111111110).
Точность: 15 – 16 десятичных знаков.
Десятичный диапазон: 10-308 – 10308.
168. Четверная точность
Число занимает 128 бита: мантисса (0– 111), порядок (112 – 126), знак (127).
Порядок имеет смещение 16383.
Минимальный порядок -16382
(000000000000001), нулевой порядок
(011111111111111), максимальный
порядок 16383 (111111111111110).
Точность: 33 – 34 десятичных знака.
Десятичный диапазон: 10-4932 – 104932.
169. Регистры (1)
Архитектура x64 предусматривает 16128-разрядных регистров xmm0 –
xmm15 для работы с данными в
формате плавающей точки. Можно
использовать весь регистр, а можно
младшую 64- или 32-разрядную часть.
Наименование регистров не меняется,
разрядность зависит от команды.
170. Регистры (2)
Базовые команды работают только соперандами в формате одинарной и
двойной точности (32 и 64 разряда).
Весь 128-разрядный регистр
используется только в специальных
векторных командах.
171. Регистры (3)
Для передачи в процедуру первыхвосьми параметров с плавающей
точкой используются регистры xmm0 –
xmm7. Возврат значения с плавающей
точкой осуществляется через xmm0.
Вызываемая процедура не гарантирует
сохранение всех 16 (xmm0 – xmm15)
регистров с плавающей точкой.
172. Регистры (4)
Если в процедуру одновременнопередаются целые значения (адреса) и
значения с плавающей точкой, то
всегда берется свободный регистр с
минимальным номером. Например, в
функцию нужно передать адрес,
значение с плавающей точкой двойной
точности и 32-разрядное целое число.
Будут использованы следующие
регистры: rdi, xmm0, esi.
173. Пересылки (1)
Одинарная точность:movss op1, op2
Двойная точность:
movsd op1, op2
Могут использоваться только регистры
xmm0 – xmm15. Только один операнд
может находится в оперативной
памяти. Непосредственных операндов
нет.
174. Пересылки (2)
Примеры:movss xmm1, xmm2
movsd qword [rbx], xmm3
movss xmm0, dword [rax+rdx*4]
175. Конвертация (1)
Преобразовать значение одинарнойточности в двойную точность:
cvtss2sd op1, op2
op1 – только регистр xmm0 – xmm15
op2 – регистр xmm0 – xmm15 или
ячейка оперативной памяти
176. Конвертация (2)
Преобразовать значение двойнойточности в одинарную точность:
cvtsd2ss op1, op2
op1 – только регистр xmm0 – xmm15
op2 – регистр xmm0 – xmm15 или
ячейка оперативной памяти
177. Конвертация (3)
Примеры:cvtss2sd xmm0, xmm1
cvtss2sd xmm2, dword [rax+rdx]
cvtsd2ss xmm3, xmm4
cvtsd2ss xmm5, qword [rcx]
178. Конвертация (4)
Преобразовать значение одинарнойточности в целое:
cvtss2si op1, op2
op1 – только РОН (64- или 32разрядный)
op2 – регистр (xmm0 – xmm15) или
ячейка оперативной памяти
179. Конвертация (5)
Преобразовать значение двойнойточности в целое:
cvtsd2si op1, op2
op1 – только РОН (64- или 32разрядный)
op2 – регистр (xmm0 – xmm15) или
ячейка оперативной памяти
180. Конвертация (6)
Преобразовать целое в значениеодинарной точности:
cvtsi2ss op1, op2
op1 – только регистр (xmm0 – xmm15)
op2 – РОН (64- или 32-разрядный) или
ячейка оперативной памяти
181. Конвертация (7)
Преобразовать целое в значениедвойной точности:
cvtsi2sd op1, op2
op1 – только регистр (xmm0 – xmm15)
op2 – РОН (64- или 32-разрядный) или
ячейка оперативной памяти
182. Конвертация (8)
Примеры:cvtss2sd xmm0, xmm1
cvtsd2ss xmm2, qword [rsi+rdi]
cvtss2si eax, xmm3
cvtsd2si rbx, qword [rax]
cvtsi2ss xmm4, ecx
cvtsi2sd xmm5, dword [rbx]
183. Арифметика (1)
Все команды двухоперандные:op1 – только регистр (xmm0 – xmm15)
op2 – регистр (xmm0 – xmm15) или
ячейка оперативной памяти
184. Арифметика (2)
Сложение одинарной точности:addss op1, op2
Сложение двойной точности:
addsd op1, op2
185. Арифметика (3)
Вычитание одинарной точности:subss op1, op2
Вычитание двойной точности:
subsd op1, op2
186. Арифметика (4)
Умножение одинарной точности:mulss op1, op2
Умножение двойной точности:
mulsd op1, op2
187. Арифметика (5)
Деление одинарной точности:divss op1, op2
Деление двойной точности:
divsd op1, op2
188. Арифметика (6)
Извлечение квадратного корняодинарной точности:
sqrtss op1, op2
Извлечение квадратного корня
двойной точности:
sqrtsd op1, op2
189. Арифметика (7)
Примеры:addss xmm0, xmm1
addsd xmm2, qword [rax]
subss xmm3, dword [rbx+rcx]
subsd xmm4, xmm5
mulss xmm6, xmm7
mulsd xmm8, xmm9
190. Арифметика (8)
Примеры:divss xmm10, xmm11
divsd xmm12, qword [rsi]
sqrtss xmm13, dword [rdi+rbp*4]
sqrtsd xmm14, xmm15
191. Арифметика (9)
Сравнение одинарной точности:ucomiss op1, op2
Сравнение двойной точности:
ucomisd op1, op2
Команды сравнения не меняют
значения операндов, а влияют только
на флаги.
192. Арифметика (10)
Примеры:ucomiss xmm0, xmm1
ucomisd xmm2, qword [rbx+rdx*8]
193. Арифметика (11)
Команды сравнения вещественныхчисел влияют на флаги: CF и ZF,
поэтому переходы по результатам
данных команд следует осуществлять
при помощи команд условного
перехода по беззнаковым условиям: ja,
jb, jae и т.п.
programming