assembly 使用循环和汇编语言中的xchg指令交换数组中的元素

jtw3ybtb  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(202)

我正在上一门汇编语言的课程,我遇到了这个问题,就是使用循环和xchg指令来交换数组中的所有元素,数组看起来像这样inputStr包含这些元素“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”。在使用循环和xchg之后,它必须看起来像这样“G”,“H”,“E”,“F”,C、D、A、B。
我已经试过很多次了,但是我的输出不正确。我不能弄清楚逻辑,或者正确的方法来做这件事。
这是我的代码,它是在x86

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode: DWORD

.data
    inputStr BYTE "A", "B", "C", "D", "E", "F", "G", "H"

.code
main PROC
    mov ecx, 8
    xor ebx, ebx
    mov ebx, offset inputStr

    l1:
       xor eax, eax
       mov al, [ebx]
       add ebx, ecx
       sub ebx, 2
       xchg al, [ebx]
       add ebx, 1
       sub ebx, ecx
       xchg al, [ebx]
       inc ebx
       dec ecx
   
       loop l1

    INVOKE ExitProcess, 0
main ENDP
END main
bq8i3lrv

bq8i3lrv1#

在一个有N个元素的数组中,为了实现反转,你可以进行N/2次交换,如果你把元素配对,就像你从一个有(N/2)个元素的数组开始,那么交换的次数就变成了(N/2)/2。
显然,你需要使用loopxchg指令。这两条指令都非常慢,所以在下一段代码中也没有理由使用更好的movzx

mov  ecx, (8 / 2) / 2        ; Number of swaps
   mov  ebx, offset inputStr
T1:
   mov  ax, [ebx]               ; Reading a pair
   xchg ax, [ebx + ecx * 4 - 2] ; Swapping a pair
   mov  [ebx], ax               ; Writing a pair
   add  ebx, 2
   loop T1

迭代的实际作用:

"A", "B", "C", "D", "E", "F", "G", "H"
        <---------------- 8 ----------------->
ECX=2   "G", "H", "C", "D", "E", "F", "A", "B"
        ^                             ^
        EBX                           EBX + 2 * 4 - 2
                                            ^
                                            ECX

        "G", "H", "C", "D", "E", "F", "A", "B"
                  <------ 4 ------->
ECX=1   "G", "H", "E", "F", "C", "D", "A", "B"
                  ^         ^
                  EBX       EBX + 1 * 4 - 2
                                  ^
                                  ECX

ECX=0
dfuffjeb

dfuffjeb2#

在64位中,它可以像这样简单:

ITEMS = 8
inputList WORD "A", "B", "C", "D", "E", "F", "G", "H"

    mov rbx, inputList
    mov ecx, ITEMS/2/2
@@:
    mov eax, [rbx]
    xchg [rbx+rcx*8-4], eax
    mov [rbx], eax

    add rbx, 4
    loop @B

它只是通过XCHG'ing成对的2字节元素来产生所需的结果。
由此,您应该能够使用AX而不是RAX很容易地构建16位变体。

相关问题