Вывод строки наоброот - Assembler
Формулировка задачи:
Здравствуйте, есть код, который выводит строку, нужно сделать программу, которая сформирует новую строку, состоящую из символов исходной строки записанных наоборот. Слабо разбираюсь в этом, долго пытался сделать, но ничего не получилось. Буду рад помощи. Код ниже
.model small .stack 100h .data Original_string db 'Assembler language programming is the fastest in the world.', 13, 10, '&' Formed_line db 255 DUP(?) .code .386 main: mov ax, @data mov ds, ax mov es, ax mov dx, offset Original_string mov ah, 9 int 21h cld mov ecx, LENGTHOF Original_string sub ecx, 0 mov esi, [OFFSET Original_string] mov edi, OFFSET Formed_line rep movsb mov dx, offset Formed_line mov ah, 9 int 21h mov ax, 4C00h int 21h end
Решение задачи: «Вывод строки наоброот»
textual
Листинг программы
.data MsgBoxText db "Win64 Assembly is Great! nmrt",10 a db lengthof MsgBoxText+1 dup(0) .code mov esi,offset a-9 mov edi,offset a mov ecx,lengthof MsgBoxText shr ecx,3 std jz a1 @@: lodsq bswap rax mov [rdi],rax add edi,8 loop @b a1: add rsi,8 mov ecx,lengthof MsgBoxText and ecx,7 @@: movsb add edi,2 loop @b cld ......
Объяснение кода листинга программы
В данном коде на языке Assembler выполняется вывод строки Win64 Assembly is Great! nmrt
в консоль. Список операций выглядит следующим образом:
- .data - определение сегмента данных, в котором будет храниться строка
- MsgBoxText db
Win64 Assembly is Great! nmrt
,10 - определение переменной, которая будет содержать строку - a db lengthof MsgBoxText+1 dup(0) - определение переменной, которая будет использоваться для хранения длины строки и в качестве индекса при выводе строки
- .code - определение сегмента кода
- mov esi,offset a-9 - перемещение указателя на переменную
a
в регистр esi - mov edi,offset a - перемещение указателя на переменную
a
в регистр edi - mov ecx,lengthof MsgBoxText - перемещение длины строки в регистр ecx
- shr ecx,3 - деление длины строки на 4 и сохранение результата в регистре ecx
- std - переход к оператору jz a1 (то есть к 10-му оператору) при условии, что результат деления равен 0
- lodsq - загрузка целого числа из памяти и сохранение его в регистре rax
- bswap rax - инвертирование байтов в регистре rax
- mov [rdi],rax - сохранение инвертированного числа в памяти по адресу, указанному в регистре edi
- add edi,8 - увеличение указателя на 8 байт (так как переменная
a
определена как строка символов, то есть один байт) - loop @b - повторение предыдущих операций (от 10 до 13) до тех пор, пока значение регистра ecx не станет равным 0
- a1: add rsi,8 - увеличение указателя на 8 байт (так как переменная
a
определена как строка символов, то есть один байт) - mov ecx,lengthof MsgBoxText - перемещение длины строки в регистр ecx
- and ecx,7 - установление значения регистра ecx равным 7 (так как длина строки должна быть кратной 8, а операция and с 7 гарантирует это)
- movsb - вывод строки из регистра edi (в котором хранится переменная
a
) в память по адресу, указанному в регистре esi - add edi,2 - увеличение указателя на 2 байта (так как переменная
a
определена как строка символов, то есть один байт) - loop @b - повторение предыдущих операций (от 15 до 19) до тех пор, пока значение регистра ecx не станет равным 0
- cld - установка режима работы с памятью, при котором происходит чтение данных из памяти, а не запись в память (при этом операция movsb будет выводить данные из памяти)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д