我遇到的问题是asm代码在与C混合时有效,但在asm代码中使用时却没有适当的参数。
;; array - RDI, x- RSI, y- RDX
getValue:
mov r13, rsi
sal r13, $3
mov r14, rdx
sal r14, $2
mov r15, [rdi+r13]
mov rax, [r15+r14]
ret
从技术上讲,我想保持rdi,rsi和rdx寄存器不受影响,因此我使用其他寄存器。
我使用的是x64机器,因此我的指针有8个字节。从技术上讲,这段代码应该是这样做的:
int getValue(int** array, int x, int y) {
return array[x][y];
}
它以某种方式在我的C代码中工作,但在以这种方式在asm中使用时不会:
mov rdi, [rdi] ;; get first pointer - first row
mov r9, $4 ;; we want second element from the row
mov rax, [rdi+r9] ;; get the element (4 bytes vs 8 bytes???)
mov rdi, FMT ;; prepare printf format "%d", 10, 0
mov rsi, rax ;; we want to print the element we just fetched
mov eax, $0 ;; say we have no non-integer argument
call printf ;; always gives 0, no matter what's in the matrix
有人能看到这个并帮助我吗?提前谢谢。
答案 0 :(得分:1)
sal r14, $2
表示元素是dwords,因此ret
之前的最后一行不应加载qword。此外,x86具有很好的缩放寻址模式,因此您可以这样做:
mov rax, [rdi + rsi * 8] ; load pointer to column
mov eax, [rax + rdx * 4] ; note this loads a dword
ret
这意味着你有一个指向 columns 的指针数组,这是不寻常的。你可以这样做,但它的目的是什么?
答案 1 :(得分:0)
这是一个标准的整数矩阵。
int** array;
sizeof(int*) == 8
sizeof(int) == 4
我怎么看,当我第一次拥有该数组时,我有一个指向内存空间的指针而没有“空白”,它一个接一个地保存所有指针(逐个索引),所以我说“让我们”转到数组的元素rsi-th“这就是为什么我用rsi-th * 8字节移位。所以现在我得到相同的情况,但指针应该指向一个整数的空间,所以4字节的项目。这就是我在那里移动4个字节的原因。
我的想法错了吗?