在程序集中反转数组

时间:2014-03-01 22:10:12

标签: arrays assembly reverse masm irvine32

我正试图弄清楚如何以一种尽可能灵活的方式反转装配中的数组。我到目前为止的代码是:

; This program takes an integer array and reverses it's elements, using a loop, the SIZE, TYPE and LENGTHOF
; operators.

TITLE lab4              (lab4.asm)

INCLUDE Irvine32.inc

.data

    arr DWORD 1h, 2h, 3h, 4h, 5h, 6h    ; Array of integers with 6 elements.
    len DWORD LENGTHOF arr / 2          ; The length of the array divided by 2.
    ;rng    DWORD LENGTHOF arr          ; The complete length of the array.

.code
main PROC

    mov eax, len    ; Moves the length (divided by 2) into the eax register.
    mov ebx, len    ; Sets the ebx register to 0 to serve as the counter.
    mov ecx, len    ; Loads the length of the array into the ecx register.
    mov edx, len    ; Sets a counter that starts at the end of the array.

    dec edx

    ; Start of the loop
    L1: 

    mov eax, arr[esi + (TYPE arr * ebx)]    ; Assigns to eax the value in the current beginning counter.

    xchg eax, arr[esi + (TYPE arr * edx) ]  ; Swaps the value in eax with the value at the end counter.

    mov arr[esi + (TYPE arr * ebx)], eax    ; Assigns the current beginning counter the value in eax.

    dec edx                 ; Decrements the end counter by 1.
    inc ebx                 ; Increments the beginning counter by 1.
    loop    L1              
    ; end of the loop

    mov ecx, LENGTHOF arr
    mov ebx, 0

    ; Start of loop
    L2:                                     ; Loop that runs through the array to check and make sure
    mov eax, arr[esi + (TYPE arr * ebx)]    ; the elements are reversed.
    inc     ebx
    call    DumpRegs
    loop    L2          
    ; End of loop

    exit
main ENDP

END main

这样可行,但仅当数组具有偶数个元素时才有效。我该怎么办才能使它适用于奇数?

1 个答案:

答案 0 :(得分:2)

一般来说,最好把它想象为2个指针。第一个指针从数组的开头开始向末端移动,第二个指针从数组的末尾开始向开始移动。

如果数组中有偶数项,则start最终将高于end。如果数组中的项目数量为奇数,则start最终将等于end。基本上,在C中你会找到类似while(start < end) { ... }的东西。

对于汇编(NASM语法),这可能看起来像这样:

;Reverse array of 32-bit "things" (integers, pointers, whatever)
;
;Input
; esi = address of array
; ecx = number of entries in array

reverseArrayOf32bit:
    lea edi,[esi+ecx*4-4]      ;edi = address of last entry
    cmp esi,edi                ;Is it a tiny array (zero or 1 entry)?
    jnb .done                  ; yes, it's done aleady

.next:
    mov eax,[esi]              ;eax = value at start
    mov ebx,[edi]              ;ebx = value at end
    mov [edi],eax              ;Store value from start at end
    mov [esi],ebx              ;Store value from end at start

    add esi,4                  ;esi = address of next item at start
    sub edi,4                  ;edi = address of next item at end
    cmp esi,edi                ;Have we reached the middle?
    jb .next                   ; no, keep going

.done:
    ret