Linux 在一组数据的末尾获取地址?
我一直在读《从头开始编程》一书,学习Linux中的汇编编程。我在解决第三章末尾的一个练习时遇到了问题。 本练习要求修改以下程序,以使用数据集末尾的地址来终止循环。这只是一个简单的程序,用于查找一组数据中的最大值,它目前只使用数字0来标记数据的结束Linux 在一组数据的末尾获取地址?,linux,assembly,gnu-assembler,Linux,Assembly,Gnu Assembler,我一直在读《从头开始编程》一书,学习Linux中的汇编编程。我在解决第三章末尾的一个练习时遇到了问题。 本练习要求修改以下程序,以使用数据集末尾的地址来终止循环。这只是一个简单的程序,用于查找一组数据中的最大值,它目前只使用数字0来标记数据的结束 #PURPOSE: This program finds the maximum number of a # set of data items. # #VARIABLES: The registers
#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:
.long 3, 67, 34, 14, 45, 75, 54, 187, 44, 87, 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 # The biggest
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 the beginning if new value
# Isn't larger
movl %eax, %ebx # Move the value as the largest
jmp start_loop # Jump to the beginning of loop
loop_exit:
# %ebx is the status code for the exit system call
# and it contains the maximum number
movl $1, %eax # 1 is the exit() system call
int $0x80
我知道我可以硬编码数据列表的长度,或者我可以将其存储在数据的第一个字节中,但是练习要求使用最后一个元素的地址终止循环。这本书提到用一个符号来标记结尾。我想我的问题是我不知道如何得到地址。如果我知道如何得到它,我可以把它储存在一个寄存器里。非常感谢您的帮助。问问自己:我知道数据的起始地址吗?我怎么知道?我知道数据的大小吗?我怎么知道的?我可以从这些信息中了解结束地址吗?带有一些适用于Mac OSX的次要mods
.data
data_items:
.long 3, 67, 34, 14, 45, 75, 54, 187, 44, 87, 22, 11, 66, 0
data_end:
.text
.globl start
start:
movl $0, %edi # Move 0 into the index register
movl data_items (, %edi, 4), %eax # Load the first data value
movl %eax, %ebx # The biggest
leal data_end, %ecx # Load and save ending address
start_loop:
leal data_items(, %edi, 4), %eax # Get address of next value
cmpl %eax, %ecx # Check to see if we've hit the end
je loop_exit
incl %edi # Increment index
movl (%eax), %eax # Load value
cmpl %ebx, %eax # Compare values
jle start_loop # Jump to the beginning if new value
# Isn't larger
movl %eax, %ebx # Move the value as the largest
jmp start_loop # Jump to the beginning of loop
loop_exit:
movl $1, %eax # 1 is the exit() system call
pushl %ebx
pushl $0
int $0x80
这是我遇到的最后一个问题。如果你知道起始地址,数据中的项数和每个元素的大小,你就能够计算出结束地址。如果你知道如何声明标签,你可以让它变得更容易,也许你可以在最后一个元素附近声明一个?这是一个非常优雅的解决方案,但是如果你只阅读了书中的三章,你就不会马上理解它,更不用说能够想出它了。首先,leal说明从未介绍过,仅在附录中提及。其次,我不确定它在前三章的任何地方解释了这样定义的data_end将具有data_items+1的最后一个元素的地址。我想知道这是否真的是预期的解决方案。话虽如此,您可以不使用data\u end,但我不知道如何在没有leal的情况下访问data\u items地址。这太棒了。但是,我们可以删除
pushl%ebx
和pushl$0
并进一步优化