Reversing an array in assembly

匿名 (未验证) 提交于 2019-12-03 09:02:45

问题:

I'm trying to figure out how to reverse an array in assembly in a way that makes it as flexible as possible. The code I have so far is this:

; 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 

This works, but only if the array has an even number of elements. What should I do to make it work for an odd number as well?

回答1:

In general it's best to imagine it as 2 pointers. The first pointer begins at the start of the array and moves towards the end, and the second pointer begins at the end of the array and moves towards the start.

If there are an even number of items in the array, eventually start will be higher than end. If there are an odd number of items in the array, eventually start will be equal to end. Basically, in C you'd be looking for something like while(start < end) { ... }.

For assembly (NASM syntax), this might look a bit like this:

;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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!