Вывод строки наоброот - 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 будет выводить данные из памяти)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д