Разворот строки MASM

Хорошо, я собираюсь об этом, возможно, это действительно сложное решение, но это первое, что пришло мне в голову.

Мне нужно написать программу на языке ассемблера, которая переворачивает «исходную» строку без использования «целевой» строки (временной переменной). Это моя попытка.

INCLUDE Irvine32.inc
.data
source BYTE "This is the source string", 0
count DWORD ? 

.code
main PROC

 mov ecx, LENGTHOF source 

L1: 
 mov count, ecx     ; save our outer loop count
 mov al,[source+0]    ; get the first character in the string

 mov ecx,LENGTHOF source  ; set out inner loop count
 mov esi, OFFSET source
 inc esi
L2:


 mov bl,[esi]
 dec esi
 mov [esi],bl
 add esi, 2
 loop L2

 mov ecx, count
 loop L1


 mov  edx,OFFSET source
 call WriteString

 exit
main ENDP

END main

Теперь... «алгоритм» для этого в основном таков: выньте первый символ из строки, переместите все остальные символы вниз на одну позицию в массиве символов, поместите символ, который вы вынули первым, в конец массива. Теперь я дошел до того, что это слишком сложно. На самом деле, как мне добраться до конца массива. Думаю, мне понадобится еще один цикл? Мне, конечно, не нужны три петли, и я даже не хочу иметь с этим дело.

Может быть, я на правильном пути и даже не знаю об этом. любые предложения, советы, код или другой алгоритм помогут!


person Dalton Conley    schedule 20.09.2010    source источник


Ответы (1)


Вы можете сделать это по-своему с помощью двух циклов. После выполнения первого цикла вам придется повторить его снова, но с уменьшением длины на единицу, чтобы текущий первый (первоначально второй) символ помещался в последнюю позицию, оставляя текущий только последний (изначально первый) символ. Затем продолжайте, пока длина не упадет до нуля.

Но это довольно неэффективно, так как у вас есть вложенные циклы, O(n2). Вот лучший алгоритм, который использует только один цикл, O(n):

set spointer to point to the first character
set epointer to point to the last character
while epointer is greater than spointer:
    save away [spointer] (the character pointed to by spointer) somewhere
    copy [epointer] to [spointer]
    copy the saved character to [epointer]
    add one to spointer
    subtract one from epointer

В основном он поддерживает начальный и конечный указатель, который сначала меняет местами первый и последний символы, а затем указатели перемещаются друг к другу.

Таким образом, во второй раз в цикле вы меняете местами второй и предпоследний символы, в третий раз — третий и предпоследний символы и так далее.

Этот процесс останавливается, когда указатели равны (для строки нечетной длины) или начальный указатель больше, чем конечный указатель (для строки четной длины).

Поскольку это может быть домашним заданием (и вы, кажется, все равно разбираетесь в x86), вам следует выполнить упражнение по преобразованию этого в ассемблер.


Если окажется, что это не домашнее задание, вы можете использовать приведенный ниже код masm32 в качестве основы. Пожалуйста, не пытайтесь выдать это за свою работу в сфере образования, так как вас почти наверняка поймают. Вы узнаете гораздо больше (в качестве домашнего задания или не в качестве домашнего задания), если займетесь преобразованием самостоятельно, я просто предоставляю запасной код, если у вас возникнут проблемы с его вводом.

.586
.model flat

.data
source byte "This is the source string", 0

.code
_main proc
    mov     esi, offset source   ; load up start pointer.

    mov     edi, offset source   ; set end pointer by finding zero byte.
    dec     edi
find_end:
    inc     edi                  ; advance end pointer.
    mov     al, [edi]            ; look for end of string.
    cmp     al, 0
    jnz     find_end             ; no, keep looking.
    dec     edi                  ; yes, adjust to last character.

swap_loop:
    cmp     esi, edi             ; if start >= end, then we are finished.
    jge     finished

    mov     bl, [esi]            ; swap over start and end characters.
    mov     al, [edi]
    mov     [esi], al
    mov     [edi], bl

    inc     esi                  ; move pointers toward each other and continue.
    dec     edi
    jmp     swap_loop

finished:
    int     3                    ; trap to enter debugger and check string.
                                 ; replace with whatever you need.
_main endp
end _main
person paxdiablo    schedule 20.09.2010