sps
sps

Reputation: 2720

How to compare addresses in x86

Below is an x86 program to find maximum number from a list of numbers. I am trying to exit from the loop when the ending address is reached. (It is marked with data_ends: label in the source code).

# 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

However as can be seen from the as output below, the line cmpl data_items(,%edi,4), data_ends has some issue.

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

Looks like syntax for cmpl instruction is wrong. How can I fix this ?

Upvotes: 2

Views: 1265

Answers (1)

Peter Cordes
Peter Cordes

Reputation: 365332

cmpl data_items(,%edi,4), data_ends has two memory operands. cmp isn't like lea. If you give it a memory operand, it loads from it.

cmp $(data_ends - data_items) / 4, %edi should do the trick. With your source code, that assembles to cmp $0xd,%edi. Note that you're not comparing addresses, you're comparing a loop counter (used as an index) against a loop count.

If you started with a pointer in a register, and incremented it by 4 each iteration, then it would make sense to compare addresses. To do that, you can compare two registers, or a register and an immediate. (A symbol address is a compile-time constant that can be used as an immediate operand. Remember you want the address itself, not what's stored there.)

For an example of both kinds of loop structure (index with offset vs incrementing a pointer and comparing against an end), see the two code blocks in my answer to another beginner question.

Also, you should put read only data in the .rodata section, not .data. And you should indent your instructions more than your labels. That helps a lot with readability.

Upvotes: 3

Related Questions