在 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
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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我想我会使用 stosb 和 lodsb 来做到这一点。 Lodsb 从 esi 获取一个字节到 al,stosb 将其存储到 edi。使用repnz,您还可以将其与非零的ecx结合起来(这是一个循环,直到ecx = 0)。
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).
字符串指令(stos*、lod*、scas*、cmps*)和循环指令已被弃用并且速度缓慢(我在某处听说过)。我宁愿使用类似的东西:
这应该很好。请注意,我使用 [esi] 中的内容加载 eax,但将其保存在 [edi] 中,ebx 的语音相同。当然,您必须根据 typeof(array) 调整操作数的大小。
编辑:
如果你想要更快的东西,试试这个:
这允许你一次交换 2 个字节,所以它应该快两倍。如果您想知道,
xchg
,异或交换和与交换都需要 3 个时钟周期才能完成,因此使用它们没有任何优势。String instructions (stos*, lod*, scas*, cmps*) and the loop instruction are deprecated and slow (I heard that somewhere). I'd rather use something like:
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:
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.