【发布时间】:2021-01-23 00:13:02
【问题描述】:
我一直在尝试将此函数转换为程序集:
void foo (int a[], int n) {
int i;
int s = 0;
for (i=0; i<n; i++) {
s += a[i];
if (a[i] == 0) {
a[i] = s;
s = 0;
}
}
}
但是出了点问题。
这就是我到目前为止所做的:
.section .text
.globl foo
foo:
.L1:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $0, -16(%rbp) /*s*/
movl $0, -8(%rbp) /*i*/
jmp .L2
.L2:
cmpl -8(%rbp), %esi
jle .L4
leave
ret
.L3:
addl $1, -8(%rbp)
jmp .L2
.L4:
movl -8(%rbp), %eax
imull $4, %eax
movslq %eax, %rax
addq %rdi, %rax
movl (%rax), %eax
addl %eax, -16(%rbp)
cmpl $0, %eax
jne .L3
/* if */
leaq (%rax), %rdx
movl -16(%rbp), %eax
movl %eax, (%rdx)
movl $0, -16(%rbp)
jmp .L3
我正在使用 .c 模块编译 .s 模块,例如,使用 int nums [5] = {65, 23, 11, 0, 34} 并返回相同的数组而不是 {65, 23, 11 , 99, 34}。
有人可以帮我吗?
【问题讨论】:
-
在
if,您已经通过将a[i]加载到eax中摧毁了rax,如果您到了这一点,它甚至被称为0。我很惊讶你甚至得到任何东西而不是崩溃。编辑:你甚至没有走那么远,因为你在.L2的条件被逆转了。 PS:学习使用调试器。 -
@Lucy:你知道
leaq (%rax), %rdx只是一种低效的mov %rax, %rdx方式吗?我有一种感觉,你期待它做其他事情,但我不确定那是什么。 -
将
lea移动到movl (%rax), %eax之前并将jle反转为jg可以修复代码。