如何在x86中比较地址

如何在x86中比较地址,x86,compare,memory-address,X86,Compare,Memory Address,下面是一个x86程序,用于从数字列表中查找最大数字。当到达结束地址时,我试图退出循环。(在源代码中用数据\u end:标签标记) 但是,从下面的as输出可以看出,行cmpl数据项(,%edi,4),数据结束有一些问题 user $ as maxNum.s -o maxNum.o maxNum.s: Assembler messages: maxNum.s:28: Error: too many memory references for `cmp' user $ 看起来cmpl指令的语法错误。

下面是一个x86程序,用于从数字列表中查找最大数字。当到达结束地址时,我试图退出循环。(在源代码中用
数据\u end:
标签标记)

但是,从下面的
as
输出可以看出,行
cmpl数据项(,%edi,4),数据结束
有一些问题

user $ as maxNum.s -o maxNum.o
maxNum.s: Assembler messages:
maxNum.s:28: Error: too many memory references for `cmp'
user $
看起来
cmpl
指令的语法错误。如何修复此问题?

cmpl数据项(,%edi,4),数据端有两个内存操作数
cmp
不像
lea
。如果给它一个内存操作数,它将从中加载

cmp$(数据结束-数据项)/4,%edi
应该可以做到这一点。使用您的源代码,将其汇编为
cmp$0xd,%edi
。请注意,您不是在比较地址,而是在比较循环计数器(用作索引)和循环计数

如果您从寄存器中的一个指针开始,并在每次迭代中递增4,那么比较地址是有意义的。为此,您可以比较两个寄存器,或者一个寄存器和一个立即数。(符号地址是一个编译时常量,可以用作立即操作数。请记住,您需要的是地址本身,而不是存储在那里的内容。)

有关这两种循环结构的示例(带偏移量的索引vs递增指针并与端点进行比较),请参见中的两个代码块


此外,您应该将只读数据放在
.rodata
部分,而不是
.data
部分。你应该缩进你的说明,而不是你的标签。这对可读性有很大帮助。

当我从寄存器中的指针开始,每次迭代递增4,并将其与
$data\u ends
进行比较时,它起到了作用。这就是我想做的。i、 比较地址。因此,将此标记为正确答案。但是,您所说的技巧,
cmp$(data\u end-data\u items)/4,%edi
会导致
分段错误:堆芯转储
。我不知道为什么会有分割错误。它看起来像是一个立即数值和寄存器值之间的比较,根本没有内存访问。@sps:两种方法都是将寄存器与立即数进行比较。在一种情况下,立即数是指针,在另一种情况下,立即数是最大循环计数器值。如果问题中的代码在执行cmp$(数据结束-数据项)/4、%edi
时出错,则说明您在其他地方有错误。使用调试器查看segfault发生的位置,因为您是对的,指令本身不可能出错。(您可以反汇编以再次检查,就像我为确保语法有效而做的那样:P)
user $ as maxNum.s -o maxNum.o
maxNum.s: Assembler messages:
maxNum.s:28: Error: too many memory references for `cmp'
user $