I have 3 different lists in the Data Section of my code. I intend to write a function to find the maximum number of these lists, whichever the user may want to use. How do I correctly pass the address of the required list to the function? And how to I obtain the values from the list using an index? I don't know the proper syntax for indexed addressing on an address I got as an argument. I couldn't find anything helpful on Google.
Here's the code:
# NAME: maxfunc.s
# PURPOSE: A modular approach of finding the maximum of lists
.section .data
# The data section has three lists for testing, change the code
# highlighted in the text section to change the list passed.
data_1:
.long 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
data_2:
.long 23, 45, 62, 13, 87, 54, 0
data_3:
.long 1, 2, 3, 3, 3, 7, 6, 5, 8, 1, 1, 0
# VARIABLES:
# 1. %edi - Will be our index variable, to access the items
# 2. %ebx - The element we're looking at currently
# 3. %eax - The maximum value we've found so far
# 4. %ecx - To store the address of the list
.section .text
# Push the address of the list we want to find the maximum of
pushl data_1
# ^
# +---> Change this to select your list
call maximum
addl $4, %esp # Reset the stack
movl %eax, %ebx
movl $1, %eax
int $0x80
.type maximum, @function
maximum:
# Setup
popl %ebp
movl %esp, %ebp
# The initial setup:
# Get the address of the list
# Set the index to 0
# Get the first item from the list
# The first item is currently the largest
movl $0, %edi
movl 8(%ebp), %ecx
movl (%ecx)(, %edi, 4), %ebx
movl %ebx, %eax
max_loop:
cmpl $0, %ebx
je exit_loop
incl %edi
movl (%ecx)(, %edi, 4), %ebx
cmpl %eax, %ebx
jle max_loop
# %ebx is greater than %eax, therefore, update max
movl %ebx, %eax
jmp max_loop
exit_loop:
# Tear down
movl %ebp, %esp
popl %ebp
ret
It doesn't compile and shows the following error:
maxfunc.s: Assembler messages:
maxfunc.s:47: Error: register value used as expression
maxfunc.s:55: Error: register value used as expression
What's the proper way to obtain the address of the data list from the register %ecx
to use for indexed addressing? Or the parameter?
My system is 64 bit, but I'm compiling it as a 32 bit binary (for compliance with this book)
Index addressing mode is like movq data_set(,%rbx,8), %rax
.
The syntax is like INSTRUCTION CONST(BASE_ADDR_REG,INDEX_REG,MULTIPLIER
)
You are allowed to omit the base register as I have in my example. The reason I omitted it is because my data address is not changing in my program, so I use it's immediate value instead.
Where data_set
is the base address (used as a constant), %rbx
is the index and 8
is the multiplier...in my case 8 bytes because I am iterating quadword values.
If I was iterating long
values, like you are, I would use 4
as my multiplier because longs are generally 4 bytes (32 bits) on x86
.
.section .data
data_set: .quad 8, 1, 98, 18, 18, 12, 18, 19, 27, 32, 9, 12, 18, 92, 255, 0
.section .text
.globl _start
# rbx, data index
# rdi, current max
# rax, current data
_start:
movq $0, %rbx # init index reg
movq data_set(,%rbx,8), %rax
movq %rax, %rdi
loop:
cmpq $0, %rax # check if end
je exit
incq %rbx
movq data_set(,%rbx,8), %rax
cmpq %rdi, %rax
jle loop
movq %rax, %rdi
jmp loop
exit:
movq $60, %rax
syscall