你确实很好地观察到了这种行为,而且(大部分情况下)是这样的纠正他们的错误。
movl $array1, %eax
vs公司
movl array1, %eax
:是,将加载第一个
eax
使用内存地址,将加载第二个
eax公司
具有来自内存(来自该地址)的32位值。
我很难理解如何真正注册商店的东西。
通用寄存器如下
eax公司
是32位寄存器(在支持64位
eax公司
是的低32位部分
rax
,即64位寄存器)。这意味着寄存器包含32位值(0或1)。没有别的了。除非您切换到不同的解释,否则调试器通常会将值显示为32位无符号十六进制整数,因为从输出来看就像十六进制一样
1234ABCD
您可以读取head中的特定位模式(每个十六进制数字正好是4位,即。
B
=11=8+2+1=1011二进制),但这并不意味着寄存器包含十六进制值,寄存器只有32位,您可以按照自己(或代码)的意愿对其进行解释。
使用索引访问数组元素
i
您可以从不同的技术中进行选择,在对数组求和的任务中,我可能会使用直接在元素上使用内存地址的原始代码,但随后您需要再使用一个寄存器来加载实际值,即:
# loop initialization
movl $array1, %eax # eax = array1 pointer
movl $array2, %ebx # ebx = array2 pointer
# TODO: set up also some counter or end address
loop_body:
# array1[i] += array2[i];
movl (%ebx), %edx # load value array2[i] from memory into edx
addl %edx, (%eax) # add edx to the array1[i] (value in memory at address eax)
# advance array1 and array2 pointers (like ++i;)
addl $4, %eax
addl $4, %ebx
# TODO: do some loop termination condition and loop
这允许使用简单的正文循环代码,并使用不同的数组提供相同的求和代码进行求和。
其他选项
通过将寄存器直接编码到内存访问指令中,可以避免使用内存地址注册,如:
# loop initialization
xorl %ecx, %ecx # ecx = 0 (index + counter)
loop_body:
# array1[i] += array2[i];
movl array2(,%ecx,4), %eax # load value array2[i] from memory into eax
addl %eax, array1(,%ecx,4) # add eax to the array1[i]
incl %ecx # ++i
# TODO: do some loop termination condition and loop
但此代码无法重定向到不同的阵列。
也可以在寄存器中使用数组地址,但通过使用索引寄存器寻址避免对其进行修改:
# loop initialization
movl $array1, %eax # eax = array1 pointer
movl $array2, %ebx # ebx = array2 pointer
xorl %ecx, %ecx # ecx = 0 (index + counter)
loop_body:
# array1[i] += array2[i];
movl (%ebx,%ecx,4), %edx # load value array2[i] from memory into edx
addl %edx, (%eax,%ecx,4) # add edx to the array1[i]
incl %ecx # ++i
# TODO: do some loop termination condition and loop
如果您确实计划使用索引值,那么这可能是有意义的,所以您需要
我
,并且您也计划稍后使用数组地址,因此不修改它们很方便,等等。。。
还有其他方法可以访问内存中的值,但对于学习x86汇编的人来说,以上方法最简单。
请记住,在汇编中没有变量或数组等。。计算机内存就像一个没有名字的巨大数组,索引从0到N-1(N=物理内存的大小),每个索引上都有一个字节(8位信息)。
寄存器类似于CPU芯片上直接可用的8/16/32/64位信息,因此CPU不需要知道地址(名称“eax”类似于地址),也不需要联系内存芯片获取值(因此寄存器比内存快)。
联系AT&中的存储器;T语法必须以以下形式编写:
displacement(base_reg, index_reg, scale)
,请详细查看此问题:
A couple of questions about [base + index*scale + disp]