2

アセンブリで文字列を逆にしようとしています。ただし、私のコードは正しく動作していないようです。読みやすくするために改行文字列を追加しました。

Linux と nasm をコンパイラとして使用しています。

アドレスポインタの値を取って正しい場所で入れ替えると、文字列が逆になって元に戻るのではないかと思っていました。

これは私のコードです:

section .data
    hello     db 'Hello world!'
    helloLen  equ $-hello
    derp db '=========',10
    derplen equ $-derp

section .text
    global main

main:
    mov eax,0
    mov ecx,helloLen

    reverse:
        ;move pointer
        mov ebx,hello
        add ebx,eax
        push eax

        ;move pointer
        mov eax,hello
        add eax,ecx
        push ecx

        ;switch bytes
        push ebx
        mov ebx,[ebx]
        mov [eax],ebx
        pop ebx
        mov eax,[eax]
        mov [ebx],eax

        ;print text
        mov eax,4
        mov ebx,1
        mov ecx,hello
        mov edx,helloLen
        int 80h

        ;Print newline
        mov eax,4
        mov ebx,1
        mov ecx,derp
        mov edx,derplen
        int 80h

        ;increment and decrement
        pop ecx
        dec ecx
        pop eax
        inc eax

        cmp eax,helloLen
    jne reverse

    end:
        mov eax,1
        mov ebx,0
        int 80h

これは私が得る出力です:

Hello world!Hell=====
Hello worldellol=====
Hello worlllo ol=====
Hello worlo w ol=====
Hello woo wow ol=====
Hello wooooow ol=====
Hello wooooow ol=====
Helloooooooow ol=====
Helloooooooow ol=====
Helooowooooow ol=====
Heoow wooooow ol=====
How o wooooow ol=====
4

2 に答える 2

7

文字を交換して文字列を逆にする方法は、最初と最後、次に 2 番目と最後から 2 番目などを交換することです。C では、次のように記述します。

for (i = 0; i < len/2; ++i)
{
    c = s[i];
    s[i] = s[len-i-1];
    s[len-i-1] = c;
}

アセンブリ言語で最も簡単な方法は、ESI および EDI レジスタが文字列の最初と最後を指すように設定してからループすることです。繰り返しごとに、ESI を増やし、EDI を減らします。結果は次のようになります。

mov ecx, helloLen
mov eax, hello
mov esi, eax  ; esi points to start of string
add eax, ecx
mov edi, eax
dec edi       ; edi points to end of string
shr ecx, 1    ; ecx is count (length/2)
jz done       ; if string is 0 or 1 characters long, done
reverseLoop:
mov al, [esi] ; load characters
mov bl, [edi]
mov [esi], bl ; and swap
mov [edi], al
inc esi       ; adjust pointers
dec edi
dec ecx       ; and loop
jnz reverseLoop
于 2012-11-27T15:41:14.467 に答える