x86-64汇编中的数组元素比较(AT& T语法)

时间:2016-05-04 04:25:44

标签: arrays assembly x86-64 att

我正在尝试在x86-64程序集中编写一个简单的过程,它只返回一个int数组的长度。数组中的最后一个元素是0,不应该计算。该数组作为来自C代码的int *传入。

我的汇编代码如下:

f1:
    movq $0, %rax   # zero out %rax
    jmp   test      # jump to test
body:
    incq  %rax      # increment %rax, which is counter and array index

test:
    cmpq   $0, (%rdi,%rax,4)  # compare (rdi + (rax * 4)) to 0
    jne    body   # jump if zero flag is not set
ret

当这个运行时,我得到的结果不正确,但也不是非常不正确,所以不是11(数组的大小减去结尾0)我得到38.我认为发生的是我的比较语句是不正确。我的想法是,由于cmpq在不改变寄存器的情况下执行(dest-src),如果数组索引为0,则0-0将产生零,因此将设置零标志,但这似乎不会发生。< / p>

我可以随意将数组中的任何元素加载到%rax中,后者返回正确的值:

movq   (%rdi,%rax,4), %rax   # %rax initially 0, so first element loaded into %rax

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

x86-64 ABI(SystemV和Windows)中的

int为32位(4字节)。 (有关详细信息,请参阅标记wiki。)

cmpq $0, (%rdi,%rax,4)正确地将索引缩放4,但错误地使用64位操作数大小。 (q代表四字。在Intel的x86术语中,“字”是16位。)

cmpq正在比较两个连续的元素。等效的C将是while( 0 != *(int64_t*)&(array[i]) ){ ++i; }

在x86之外,一个单词通常是机器的寄存器大小或类似的东西,所以它匹配long的大小。例如一个字是32位MIPS上的32位。

这只是术语,方便的名称如word(AT&amp; T语法w后缀),dword(l后缀),qword(q后缀)很方便。< / p>

gdb中,在某些地方,即使在调试x86时,“word”也是32位(例如转储内存的x命令有b(字节),h(半字:16b),w(字)和g(巨型:8B)尺寸格式说明符。