Вывод строки наоброот - 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 в консоль. Список операций выглядит следующим образом:

  1. .data - определение сегмента данных, в котором будет храниться строка
  2. MsgBoxText db Win64 Assembly is Great! nmrt,10 - определение переменной, которая будет содержать строку
  3. a db lengthof MsgBoxText+1 dup(0) - определение переменной, которая будет использоваться для хранения длины строки и в качестве индекса при выводе строки
  4. .code - определение сегмента кода
  5. mov esi,offset a-9 - перемещение указателя на переменную a в регистр esi
  6. mov edi,offset a - перемещение указателя на переменную a в регистр edi
  7. mov ecx,lengthof MsgBoxText - перемещение длины строки в регистр ecx
  8. shr ecx,3 - деление длины строки на 4 и сохранение результата в регистре ecx
  9. std - переход к оператору jz a1 (то есть к 10-му оператору) при условии, что результат деления равен 0
  10. lodsq - загрузка целого числа из памяти и сохранение его в регистре rax
  11. bswap rax - инвертирование байтов в регистре rax
  12. mov [rdi],rax - сохранение инвертированного числа в памяти по адресу, указанному в регистре edi
  13. add edi,8 - увеличение указателя на 8 байт (так как переменная a определена как строка символов, то есть один байт)
  14. loop @b - повторение предыдущих операций (от 10 до 13) до тех пор, пока значение регистра ecx не станет равным 0
  15. a1: add rsi,8 - увеличение указателя на 8 байт (так как переменная a определена как строка символов, то есть один байт)
  16. mov ecx,lengthof MsgBoxText - перемещение длины строки в регистр ecx
  17. and ecx,7 - установление значения регистра ecx равным 7 (так как длина строки должна быть кратной 8, а операция and с 7 гарантирует это)
  18. movsb - вывод строки из регистра edi (в котором хранится переменная a) в память по адресу, указанному в регистре esi
  19. add edi,2 - увеличение указателя на 2 байта (так как переменная a определена как строка символов, то есть один байт)
  20. loop @b - повторение предыдущих операций (от 15 до 19) до тех пор, пока значение регистра ecx не станет равным 0
  21. cld - установка режима работы с памятью, при котором происходит чтение данных из памяти, а не запись в память (при этом операция movsb будет выводить данные из памяти)

Оцени полезность:

9   голосов , оценка 4 из 5