2

好吧,我正在解决这个问题,这可能是一个非常复杂的解决方案,但它首先出现在我的脑海中。

我需要编写一个汇编语言程序来反转“源”字符串,而不使用“目标”字符串(临时变量)..这是我的尝试。

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

现在..这个“算法”基本上是这样的:从字符串中取出第一个字符,在字符数组中将所有其他字符向下移动一个空格,将你第一次取出的字符放在数组的后面。现在,我到了这太复杂的地步了。事实上,我如何到达数组的后面。我想我需要另一个循环?我当然不需要三个循环,甚至不想处理它。

也许我在正确的轨道上,甚至不知道。任何建议、提示、代码或不同的算法都会有所帮助!

4

1 回答 1

4

可以用两个循环来做。完成第一个循环后,您必须再次执行此操作,但长度减一,以便将当前的第一个(最初是第二个)字符放在倒数第二个位置,只留下当前的最后一个(最初是第一个)字符. 然后继续前进,直到长度降至零。

但这非常低效,因为您有嵌套循环 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
于 2010-09-20T01:42:18.673 回答