开发者

most effective way to invert an array in nasm assembly?

working on inverting my array, i have code already taht will print it out, i was thinking of creating a second array, storing it into it, then printing that one out, but is there an easier way?

segment .bss  
    newarray    resd    40  
    segment .data  
    arrayis     db  "Inverted Array is: ", 0  
    space       db  ", ", 0  
    thanks      db  "Thanks", 0  
s开发者_如何学编程egment .text
    extern readdouble,print_string, read_int, writedouble, print_nl, print_int
    global invertarray
invertarray:
    pusha
    mov ebx, [ebp]  ;moves starting location of array1 into ebx
    mov edi, [ebp+12]   ;move quantity into edi 
    mov esi, 0      ;set esi to 0
    mov eax, arrayis    ;
    call    print_string    ;

    fld qword [ebx]
    mov ecx, [ebx]  ;move higher order into ecx
    mov edx, [ebx+4]    ;move lower order into edx
    call    writedouble

    mov eax, space  ;
    call    print_string    ;

topofloop:
    mov ecx, [ebx]  ;move higher order into ecx
    mov edx, [ebx+4]    ;move lower order into edx

    fld qword [ebx] ;move the first item of the stack onto st0
    add ebx, 8      ;increment to next location
    inc esi

    mov ecx, [ebx]  ;move first set of bits
    mov edx, [ebx+4]    ;move the second set of bits
    call    writedouble ;write the number

    mov eax, space  ;
    call    print_string    ;

    cmp esi, edi    ;compare to see if all items have been printed
    jz  done_loop   ;
    jmp topofloop   ;go back to top of the loop

done_loop:  
    popa
    ret


I think i would use stosb and lodsb in order to do that. Lodsb gets a byte to al from esi and stosb stores it to edi. using repnz you can also combine it with ecx being non zero (it's a loop till ecx = 0).


String instructions (stos*, lod*, scas*, cmps*) and the loop instruction are deprecated and slow (I heard that somewhere). I'd rather use something like:

    mov    esi, start_of_array       # esi points to array's begin
    mov    edi, esi
    add    edi, length_of_array      # and edi to array's end
    dec    edi                       # skip terminating null byte

loop:
    mov al, [esi]                   # load the dwords
    mov bl, [edi]
    mov [edi], al                   # and save them
    mov [esi], bl
    inc esi
    dec esi
    cmp esi, edi                     # check if we are before in array's middle
    jb loop

This should word fine. Note that I load eax with what's in [esi] but save it in [edi], same speech for ebx. Of course you have to adjust operands' size according to typeof(array).

EDIT: if you want something faster try this:

loop:
    mov ax, [esi]
    mov bx, [edi]
    xchg al, ah
    xchg bl, bh
    mov [esi], bx
    mov [edi], ax
    add esi, 2
    dec edi, 2
    cmp esi, edi
    jb loop

This allows you to swap 2 bytes at time, so it should be two times faster. If you're wondering, xchg, the xor swap and the and swap take both 3 clock cycles to complete, so no advantage in using them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜