如何在 x86 中比较地址
How to compare addresses in x86
下面是一个 x86 程序,用于从数字列表中查找最大数字。当到达结束地址时,我试图退出循环。 (在源码中用data_ends:
标签标注)
# 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 [=10=], %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 , %eax
int [=10=]x80
然而,从下面的 as
输出可以看出,cmpl data_items(,%edi,4), data_ends
行有一些问题。
user $ as maxNum.s -o maxNum.o
maxNum.s: Assembler messages:
maxNum.s:28: Error: too many memory references for `cmp'
user $
cmpl
指令的语法似乎有误。我该如何解决这个问题?
cmpl data_items(,%edi,4), data_ends
有两个内存操作数。 cmp
不像 lea
。如果你给它一个内存操作数,它就会从中加载。
cmp $(data_ends - data_items) / 4, %edi
应该可以解决问题。使用您的源代码,汇编为 cmp [=14=]xd,%edi
。请注意,您 不是 比较地址,而是将循环计数器(用作索引)与循环计数进行比较。
如果您从寄存器中的指针开始,每次迭代将其递增 4,那么比较地址就有意义了。为此,您可以比较两个寄存器,或一个寄存器和一个立即数。 (符号地址是一个编译时常量,可用作立即操作数。请记住,您需要的是地址本身,而不是存储在那里的内容。)
有关两种循环结构的示例(带偏移的索引与递增指针和比较结束),请参阅 my answer to another beginner question.
中的两个代码块
此外,您应该将只读数据放在 .rodata
部分,而不是 .data
。你应该缩进你的说明而不是你的标签。这有助于 lot 的可读性。
下面是一个 x86 程序,用于从数字列表中查找最大数字。当到达结束地址时,我试图退出循环。 (在源码中用data_ends:
标签标注)
# 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 [=10=], %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 , %eax
int [=10=]x80
然而,从下面的 as
输出可以看出,cmpl data_items(,%edi,4), data_ends
行有一些问题。
user $ as maxNum.s -o maxNum.o
maxNum.s: Assembler messages:
maxNum.s:28: Error: too many memory references for `cmp'
user $
cmpl
指令的语法似乎有误。我该如何解决这个问题?
cmpl data_items(,%edi,4), data_ends
有两个内存操作数。 cmp
不像 lea
。如果你给它一个内存操作数,它就会从中加载。
cmp $(data_ends - data_items) / 4, %edi
应该可以解决问题。使用您的源代码,汇编为 cmp [=14=]xd,%edi
。请注意,您 不是 比较地址,而是将循环计数器(用作索引)与循环计数进行比较。
如果您从寄存器中的指针开始,每次迭代将其递增 4,那么比较地址就有意义了。为此,您可以比较两个寄存器,或一个寄存器和一个立即数。 (符号地址是一个编译时常量,可用作立即操作数。请记住,您需要的是地址本身,而不是存储在那里的内容。)
有关两种循环结构的示例(带偏移的索引与递增指针和比较结束),请参阅 my answer to another beginner question.
中的两个代码块此外,您应该将只读数据放在 .rodata
部分,而不是 .data
。你应该缩进你的说明而不是你的标签。这有助于 lot 的可读性。