This is a program given in the book 'Programming from the ground up' by Jonathan Bartlett to find the maximum number in a list:
#PURPOSE: This program finds the maximum number of a
# set of data items.
#
#VARIABLES: The registers have the following uses:
#
# %edi - Holds the index of the data item being examined
# %ebx - Largest data item found
# %eax - Current data item
#
# The following memory locations are used:
#
# data_items - contains the item data. A 0 is used
# to terminate the data
#
.section .data
data_items: #These are the data items
.long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
.section .text
.globl _start
_start:
movl $0, %edi # move 0 into the index register
movl data_items(,%edi,4), %eax # load the first byte of data
movl %eax, %ebx # since this is the first item, %eax is
# the biggest
start_loop: # start loop
cmpl $0, %eax # check to see if we’ve hit the end
je loop_exit
incl %edi # load next value
movl data_items(,%edi,4), %eax
cmpl %ebx, %eax # compare values
jle start_loop # jump to loop beginning if the new
# one isn’t bigger
movl %eax, %ebx # move the value as the largest
unfortunately the assembly programs given in the book are for 32 bit processors FWIU. So I'm translating the programs for 64 bit with some help from https://cs.lmu.edu/~ray/notes/gasexamples/. Here is my code(which is not working) for 64 bit systems:
#variables: the registers have the following uses:
# %rdx - holds the index of the data item being examined
# %rbx - largest data item found
# %rcx - current data item
# the following memory locations are used:
# data_items - contains the item data. 0 is used to terminate the data.
data_items:
.long 8,9,3,4,15,8,0
.global _start
.text
_start:
mov $0, %rdx # move 0 into the index register
mov data_items(,%rdx,4), %rcx # load the first byte of data
mov %rcx, %rbx # since this is the first item, %rcx is the biggest
start_loop:
cmp $0, %rcx # check to see if we've hit the end
je loop_exit
inc %rdx # load next value
mov data_items(,%rdx,4), %rcx
cmp %rbx, %rcx
jle start_loop
mov %rcx, %rbx # move the value as the largest
jmp start_loop
loop_exit:
#%rdi is the status code for the exit system call
mov $60, %rax
mov %rbx, %rdi # moving the final value in %rbx to %rdi to return
syscall
What is wrong in my code?
I suspect that .long
doesn't work the same way in 64 bit assembly code.
I tried to debug the code in gdb here is the output:
Reading symbols from ./a.out...
(gdb) break 1
Breakpoint 1 at 0x401000: file max.s, line 11.
(gdb) run
Starting program: /home/hackasaur/Desktop/assembly/a.out
Breakpoint 1, _start () at max.s:11
11 mov $0, %rdx # move 0 into the index register
(gdb)stepi
12 mov data_items(,%rdx,4), %rcx # load the first byte of data
(gdb) info registers
rax 0x0 0
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7ffffffee160 0x7ffffffee160
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x401007 0x401007 <_start+7>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) stepi
13 mov %rcx, %rbx # since this is the first item, %rcx is the biggest
(gdb) info registers
rax 0x0 0
rbx 0x0 0
rcx 0x900000008 38654705672
rdx 0x0 0
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7ffffffee160 0x7ffffffee160
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0x0 0
r13 0x0 0
r14 0x0 0
r15 0x0 0
rip 0x40100f 0x40100f <_start+15>
eflags 0x202 [ IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
I found that there is this gibberish value 38654705672
getting loaded in rcx register in the line 12 mov data_items(,%rdx,4), %rcx
instead of 8. Every time something is loaded using mov data_items(,%rdx,4), %rcx
some big gibberish value is loaded.
I am using this command to assemble and link:
as max.s -o max.o && ld max.o && ./a.out
and I'm getting an exit code of 4 for the above list of numbers using echo $?
which should be 15 in this case if it worked correctly.