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

さて、これの「アルゴリズム」は基本的にこれです:文字列から最初の文字を取り出し、他のすべての文字を文字配列の1スペース下に移動し、最初に取り出した文字を配列の後ろに置きます。今、私はこれが非常に複雑になるところまで来ています。実際、配列の最後に到達するにはどうすればよいですか。別のループが必要になると思いますか?私は確かに3つのループを必要としないか、それを処理したいとさえ思っています。

たぶん私は正しい方向に進んでいて、それさえ知らないでしょう。提案、ヒント、コード、または別のアルゴリズムが役立ちます!

4

1 に答える 1

4

あなたは2つのループでそれをあなたのやり方で行うことができます。最初のループを実行した後、もう一度実行する必要がありますが、長さを1つ減らして、現在の最初(元々は2番目)の文字が最後から2番目の位置に配置され、現在の最後(元々は最初)の文字だけが残ります。 。次に、長さがゼロになるまで続けます。

ただし、ネストされたループO(n 2)があるため、これはかなり非効率的です。これは、1つのループ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

基本的に、最初と最後の文字を交換する開始ポインタと終了ポインタを維持し、次にポインタが互いに向かって移動します。

したがって、ループを2回目に通過するときは、最後から2番目と最後から2番目の文字を交換し、3回目は最後から3番目と最後から3番目の文字を交換します。

このプロセスは、ポインターが等しい場合(奇数の長さのストリングの場合)、または開始ポインターが終了ポインターよりも大きい場合(偶数の長さのストリングの場合)に停止します。

これは宿題かもしれないので(そしてとにかく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 に答える