问题描述
该程序(摘自Jonathan Bartlett的 从头开始编程 )用.long
循环访问存储在内存中的所有数字,并在程序完成时将最大的数字放入EBX寄存器中以供查看.
This program (from Jonathan Bartlett's Programming From the Ground Up) cycles through all the numbers stored in memory with .long
and puts the largest number in the EBX register for viewing when the program completes.
.section .data
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
movl data_items (,%edi,4), %eax
movl %eax, %ebx
start_loop:
cmpl $0, %eax
je loop_exit
incl %edi
movl data_items (,%edi,4), %eax
cmpl %ebx, %eax
jle start_loop
movl %eax, %ebx
jmp start_loop
loop_exit:
movl $1, %eax
int $0x80
我不确定该程序中(,%edi,4)
的用途.我读过逗号是分开的,而4是为了提醒我们的计算机,数据项中的每个数字都是4字节长.既然我们已经声明每个数字都是.long的4个字节,那么为什么我们需要在这里再次进行呢?另外,有人可以详细说明这两种逗号在这种情况下的作用是什么吗?
I'm not certain about the purpose of (,%edi,4)
in this program. I've read that the commas are for separation, and that the 4 is for reminding our computer that each number in data items is 4 bytes long. Since we've already declared that each number is 4 bytes with .long, why do we need to do it again here? Also, could someone explain in more detail what purpose the two commas serve in this situation?
推荐答案
在AT& T语法中,内存操作数具有以下语法 :
In AT&T syntax, memory operands have the following syntax:
displacement(base_register, index_register, scale_factor)
但是很明显,如果您省略了基址寄存器,则必须保留逗号,否则汇编程序将无法理解您遗漏了哪些组件.
but obviously the commas must be retained if you omit the base register, otherwise it would be impossible for the assembler to understand which of those components you are leaving out.
所有这些数据通过以下公式组合起来以计算出您指定的地址:
All this data gets combined to calculate the address you are specifying, with the following formula:
effective_address = displacement + base_register + index_register*scale_factor
(顺便说一句,这几乎就是您在Intel语法中指定的方式).
(which incidentally is almost exactly how you would specify this in Intel syntax).
因此,有了这些知识,我们就可以对您的指令进行解码:
So, armed with this knowledge we can decode your instruction:
movl data_items (,%edi,4), %eax
匹配上面的语法,您会看到:
Matching the syntax above, you see that:
-
data_items
是位移; -
base_register
被省略,因此没有放在上面的公式中; -
%edi
是index_register
; -
4
是scale_factor
.
data_items
is the displacement;base_register
is omitted, so is not put into the formula above;%edi
isindex_register
;4
isscale_factor
.
因此,您要告诉CPU从位置data_items+%edi*4
到寄存器%eax
l l .
So, you are telling the CPU to move a long from the location data_items+%edi*4
to the register %eax
.
*4
是必需的,因为数组的每个元素都为4字节宽,因此要将索引(在%edi
中)转换为从数组开始处的偏移量(以字节为单位),您必须将其乘以乘4.
The *4
is necessary because each element of your array is 4-bytes wide, so to transform the index (in %edi
) to an offset (in bytes) from the start of the array you have to multiply it by 4.
汇编器是底层工具,对类型一无所知.
Assemblers are low level tools that knows nothing about types.
-
.long
不是数组声明,只是对汇编程序的指令,以发出与其参数的32位表示形式相对应的字节; -
data_items
不是数组,只是一个符号,它解析为某些存储位置,与其他标签完全相同.您在其后放置.long
指令的事实对汇编器没有特别的意义.
.long
is not an array declaration, is just a directive to the assembler to emit the bytes corresponding to the 32-bit representation of its parameters;data_items
is not an array, is just a symbol that gets resolved to some memory location, exactly as the other labels; the fact that you placed a.long
directive after it is of no particular significance to the assembler.
注释
Notes
- 从技术上讲,还有段说明符,但是鉴于我们在Linux上谈论的是32位代码,我将完全省略段,因为它们只会增加混乱.
这篇关于汇编:此程序中movl data_items(,%edi,4),%eax的作用是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!