如何比较x86中的地址

时间:2015-11-13 11:52:54

标签: x86 compare memory-address

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

# Program to find maximum number
# Program should end when an ending address is reached
.section .data
.globl data_items                   
data_items:
#These are the data items
.long 3,67,34,222,45,75,54,34,44,33,22,11,66
data_ends:
.section .text
.globl _start                        
_start:
movl $0, %edi                        
movl data_items(,%edi,4), %eax       
movl %eax, %ebx                      
start_loop:
incl %edi
# Problem in below line
cmpl data_items(,%edi,4), data_ends
je loop_exit
movl data_items(,%edi,4), %eax
cmpl %ebx, %eax
jle start_loop
movl %eax, %ebx
jmp start_loop
loop_exit:
movl $1, %eax
int $0x80

但是从下面的as输出中可以看出,cmpl data_items(,%edi,4), data_ends行存在一些问题。

user $ as maxNum.s -o maxNum.o
maxNum.s: Assembler messages:
maxNum.s:28: Error: too many memory references for `cmp'
user $

看起来cmpl指令的语法错误。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

cmpl data_items(,%edi,4), data_ends有两个内存操作数。 cmplea不同。如果给它一个内存操作数,它将从中加载。

cmp $(data_ends - data_items) / 4, %edi应该做到这一点。使用源代码,汇编到cmp $0xd,%edi。请注意,您比较地址,您将循环计数器(用作索引)与循环计数进行比较。

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

对于两种循环结构的示例(带偏移量的索引与递增指针并与末端进行比较),请参阅my answer to another beginner question中的两个代码块。

此外,您应该将只读数据放在.rodata部分,而不是.data。而且你应该比标签更多地缩进你的指示。这有助于 lot 具有可读性。