如何将列表程序的此程序集最大数目从32位移植到x86-64?

问题描述

这是乔纳森·巴特利特(Jonathan Bartlett)在书“ Programming from the ground up”中给出的程序,用于查找列表中的最大数目:

#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,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(,%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

不幸的是,本书中给出的汇编程序适用于32位处理器FWIU。因此,我在https://cs.lmu.edu/~ray/notes/gasexamples/的帮助下将程序翻译为64位。这是我的64位系统代码(不起作用):

#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,%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(,%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     

我的代码有什么问题?

我怀疑.long在64位汇编代码中的工作方式不同。

我试图在gdb中调试代码,这是输出

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(,%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            

我发现在第12行38654705672而不是第8行的rcx寄存器中加载了这个乱码值mov data_items(,%rcx,每次使用mov data_items(,%rcx加载内容时,都会有一个大的乱码值加载。

我正在使用以下命令进行组装和链接as max.s -o max.o && ld max.o && ./a.out 并且我使用echo $?得到了上面数字列表的退出代码4,如果可以正常工作,在这种情况下应该为15。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)