在asm x64中获取数组值

时间:2013-03-24 16:12:40

标签: arrays assembly 64-bit x86-64

我遇到的问题是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

有人能看到这个并帮助我吗?提前谢谢。

2 个答案:

答案 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个字节的原因。

我的想法错了吗?