- •Начнем же разбор сей «ужасной программы»
- •Первая строчка
- •Вторая строчка – я не разбирался
- •Поговорим о стеке
- •Второй абзац
- •Третий абзац
- •Четвертый абзац
- •Пятый абзац
- •Шестой и седьмой абзацы
- •Восьмой и девятый абзацы
- •10) Десятый и одиннадцатый абзацы или нахождение среднего арифметического я расписывать не буду, у меня по варианту другое требуется, кому надо, тот и сам все поймет.
- •11) Двенадцатый абзац
- •13) Четырнадцатый абзац и до конца
Третий абзац
.code ;начало сегмента кода
main: ;начало процедуры main
mov ax, @data ;аносим адрес сегмента данных в регистр AX
mov ds, ax ; AX в Ds
А) В сегменте кода, мы пишем саму программу, обозначим начало этого сегмента:
.code ;начало сегмента кода
Б) Вся наша программа состит из нескольких процедур (подпрограмм), в паскале для их обозначения служат «begin» и «end», в С ++ процедуры пишут в скобочках «{ }». Например циклы for, while, if и т.д. В ассемблере указывается имя процедуры и ставится «:» которое говорит о начале процедуры.
main: ;Придумываем от балды имя процедуры «main» и начинаем ее
В) Для того чтобы программа знала где хранятся наши переменные (input, middle, output, x, y, z и т.д.) мы загружаем в специальный регистр DS (регистр сегмента данных) адрес сегмента данных через регистр AX.
mov ax, @data ;Заносим адрес сегмента данных (@data) в регистр AX
mov ds, ax ; Записываем значение регистра AX в регистр Ds
Примечание:
- По идее «data» - это вся область памяти, выделенная для хранения переменных. Но когда мы пишем в команде «mov» (перемещение) «@data» прграмма запишет в регистр АХ адрес только первого байта сегмента данных.
Четвертый абзац
xor ax,ax ;очистка регистров
xor bx,bx
xor dx,dx
xor cx,cx
Перед работой основной программы, мы приравниваем НУЛЮ значение каждого регистра, для дальнейшей работы.
XOR – это операция исключающая или. Когда мы производим эту операцию над двумя одинаковыми числами 0 0 и 1 1 в результате будет 0.
А |
В |
А xor B |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
Можно сделать то же самое вычитанием: sub ax,ax
Можно сделать то же самое перемещением: mov ax, 0
Пятый абзац
m0:
mov ah, 01h
int 21h
mov input[bx],al
inc bx
inc dl
cmp dl, 03h
jle m0
call LF0D ;вызов процедуры "перевод строки - возврат каретки"
inc dh
xor dl,dl
cmp dh, 09h
jle m0
Данный кусок программы служит для считывания с клавиатуры 10 чисел по 2 байта, записанных в 16-ричном формате. Число в 2 байта – это 4-ре 16-ичных числа.
Например мы будем сравнивать числа: А7А0, А567, F5DC, и т.п. На данном этапе мы записываем по букве(числу) в каждый байт. Например, число А7F0: А-в первый байт, 7-во второй байт, F-в третий, 0-в четвертый байт.
Получается достаточно интересно, что число в 2 байта, мы записываем в 4-х байтах. На самом деле с клавиатуры мы считываем в память не числа и буквы, а ASCII коды чисел и букв. Например числа от 0 до 9 запишутся вообще как числа от 48 до 57.
А поскольку в таблице всего 256 символов – для хранения одного номера числа или буквы нам потребуется как раз один байт.
Разберем же алгоритм самой программы «m0»:
Считываем в input[1] номер первого символа первого числа (например чсило А7F0, и его первый символ А)
Считываем в input[2] номер второго символа (7-во второй байт)
Считываем в input[3] номер третего символа (F-в третий байт)
Считываем в input[4] номер четвертого символа (0-в четвертый байт)
Считываем в input[5] номер первого символа второго числа
И т.д.
Перейдем к тексту программы:
Когда мы перемещаем в регистр АН число 01, а после командуем int 21, у нас происходит прерывание для считывания чисел введенных с клавиатуры. Введенный символ сохраняется в регистре AL:
mov ah, 01h
int 21h
mov input[bx],al
После мы в цикле увеличиваем значение регистра dl на единицу 4 раза, для считывания первого числа:
inc bx ; увеличиваем на 1 номер числа в памяти (input[1], input[2] … input[40]) inc dl ; увеличиваем dl на 1 (сначала 0, потом 1, потом 2, потом 3)
cmp dl, 03h ; Сравниваем значение регистра dl с числом 3
jle m0 ; «jle» означает если меньше либо равно, переходим в начало цикла к метке «m0:»
После того, как мы полностью ввели первое число, мы переходим на новую строку:
call LF0D ;вызов процедуры "перевод строки - возврат каретки"
Затем увеличиваем на 1 номер числа (было 0 стало 1) из 10 требуемых:
inc dh
Очищаем счетчик от 0 до 3-х включительно
xor dl,dl
И следим за тем, чтобы считать ровно 10-ять 4-рехбайтных чисел
cmp dh, 09h ; Сравниваем номер считываемого числа с 9 (10 чисел от 0 до 9)
jle m0 ; Если меньше либо равно переходим к начальной метке цикла «m0:»
Итог мы считали в память 10-ять 4-ехбайтных чисел, значение каждого байта соответствует номеру числа (0, 1, … 9, A, B, C, D, E, F, a, b, c, d, e, f) в ASCII таблице.
