2011-03-18 5 views
2

내 배열을 뒤집는 작업을하고 있는데, 코드를 이미 인쇄 했으므로 두 번째 배열을 만들어서 저장하고 그 중 하나를 인쇄하는 것이 더 쉬운 방법일까요?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 

답변

1

나는 이렇게하기 위해 stosb와 lodsb를 사용할 것이라고 생각합니다. Lodsb는 esi와 stosb에서 al에게 바이트를 가져 와서 edi에 저장합니다. repnz를 사용하여 ecx를 0이 아닌 ecx와 결합 할 수도 있습니다 (ecx = 0까지 루프입니다).

+0

윙윙 거리는 소리를 듣지 않으시겠습니까? – John

+0

도움이되기를 바랍니다. http://classes.engr.oregonstate.edu/eecs/winter2011/cs271/resources/demo6.asm – Spyros

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 (array)에 따라 피연산자의 크기를 조정해야합니다.

편집 : 당신이 뭔가 빨리이 시도하려는 경우 : 이것은 당신이 한 번에 2 바이트를 교환 할 수 있습니다

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 

, 그것은 두 배 더 빠르게 처리 될 수 있도록. 궁금한 점이 있다면 xchg, xor 스왑과 스왑은 모두 3 클럭주기를 거치므로 사용시 장점이 없습니다.

관련 문제