我试图在x64汇编程序的堆栈中声明一个“四字”数组。我知道如何在.data
段中声明数组,但如果可能的话,我希望将数组设置为main
的本地数组。我知道我可能也可以使用malloc
和动态内存分配来实现此操作。但我首先想看看是否有可能在堆栈上执行此操作。我的问题是我在堆栈上声明了足够的内存来存储数组(为了更好地度量,还需要一些额外的空间)。我将初始值存储到数组元素中,但我不知道如何“迭代"索引。我想对数组中的所有值求和,只是为了练习。我尝试使用movq
检索元素,从数组的起始索引开始偏移,但我不能在”scaled index“模式下使用负索引。
...
subq $128, %rsp
movq $100, -8(%rbp) # arr[0] = 100
movq $79, -16(%rbp) # arr[1] = 79
movq $85, -24(%rbp) # arr[2] = 85
movq $62, -32(%rbp) # arr[3] = 62
movq $91, -40(%rbp) # arr[4] = 91
movq $0, -48(%rbp) # sum = 0
movq $5, %rcx # movq i = 5
loop:
cmp $1, %rcx
jz done
movq (%rbp, %rcx, 8), %rax # I believe this line may be wrong because the array starts at index -8(%rbp), right?
addq %rax, -48(%rbp)
subq $1, %rcx
jmp loop
...
1条答案
按热度按时间cuxqih211#
在这个答案中,我展示了几种修改代码的方法,第一种是对原始代码进行最小的修改,使其正常工作;最后一个是我的写法。
第一个例子只改变了rcx的起始值和结束值,它以不寻常的自上而下的顺序将数组留在堆栈中,并从数组的末尾迭代到数组的开头。
下一个示例以通常的方式将数组放入内存中,索引0位于最低地址,并从索引0迭代到4。请注意load指令上的偏移量,该偏移量导致索引0访问rbp-40。
最后一个例子改变了一些其他的东西,以匹配我的写作方式:
这个版本将总和保存在寄存器中而不是内存中。它利用了这样一个事实,即写入64位寄存器的下半部分会清除寄存器的上半部分。它使用通常的技术将0加载到寄存器中。它将循环条件放在循环的底部而不是顶部。