在nasm汇编中反转数组的最有效方法?

时间:2011-03-18 23:12:39

标签: assembly nasm

正在进行反转我的数组,我已经将代码打印出来了,我正在考虑创建第二个数组,将其存储到其中,然后将其打印出来,但有更简单的方法吗?

segment .bss  
    newarray    resd    40  
    segment .data  
    arrayis     db  "Inverted Array is: ", 0  
    space       db  ", ", 0  
    thanks      db  "Thanks", 0  
segment .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

2 个答案:

答案 0 :(得分:1)

我想我会用stosb和lodsb来做到这一点。 Lodsb从esi获得了一个字节,stosb将它存储到edi。使用repnz你也可以把它与非零的ecx结合起来(这是一个直到ecx = 0的循环)。

答案 1 :(得分:0)

字符串指令(stos *,lod *,scas *,cmps *)和循环指令已弃用且速度很慢(我听说过某处)。我宁愿使用类似的东西:

    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

这应该没问题。请注意,我使用[esi]中的内容加载eax,但将其保存在[edi]中,同样的语音保存为ebx。当然,你必须根据typeof(数组)调整操作数的大小。

修改 如果你想要更快的东西试试这个:

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

这允许您在时间交换2个字节,因此 应该快两倍。如果您想知道xchg,xor swap和and swap需要3个时钟周期才能完成,因此使用它们没有任何优势。