MASM обращение строки - PullRequest
       10

MASM обращение строки

2 голосов
/ 20 сентября 2010

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

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

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

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

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

1 Ответ

3 голосов
/ 20 сентября 2010

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

Но это довольно неэффективно, поскольку у вас есть вложенные циклы, O (n 2 ).Вот лучший алгоритм, который использует только один цикл, 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...