使用带有32位汇编程序代码的nasm会产生意外的结果,因为我当前尝试编写一个基本上交换向量元素的循环。鉴于ESI
和EDI
指向两个不同的向量(存储double
值)和ECX
描述交换第一个n
的数字n
来自[ESI]
的元素与n
元素的[EDI]
元素到目前为止我的尝试看起来像这样:
; c-call: dswap(int n, double* dx, int unused1, double* dy, int unused2)
_dswap:
push ebp
mov ebp, esp
pusha
mov esi, [ebp+12] ; dx
mov edi, [ebp+20] ; dy
mov ecx, [ebp+8] ; n
; unused1 and unused2 obviously unused for the moment
mainLoop:
cmp ecx, 0
je exitFunction
mov eax, [esi + 4 * ecx]
mov ebx, [edi + 4 * ecx]
mov [esi + 4 * ecx], ebx
mov [edi + 4 * ecx], eax
dec ecx
jmp mainLoop
exitFunction:
popa
mov esp, ebp
pop ebp
ret
我有一些意想不到的行为。使用dswap
和(1,2,3)
在(4,5,6)
上拨打n=3
只会交换两个向量中的前两个元素,从而让我想到我在这里做错了什么。
答案 0 :(得分:2)
你正在处理双打,但你只是将ecx
乘以4(浮点数的大小)。由于double的大小是8,所以你应该乘以8。
另一个问题是,在乘以它之前不要递减ecx
。假设n
传递为3,您将在第一次迭代时使用dy [3]交换dx [3],但这超出了数组的末尾。要解决此问题,您可以在进行交换之前减少ecx
。
答案 1 :(得分:0)
双精度值通常存储在8字节单元格中。在你的循环中,你假设一个4字节的单元格,这就是为什么只有一半的数组被交换。