我正在尝试组装clEnqueueFillBuffer
。
这就是我要尝试用C语言编写的内容:
for loop
这是我的汇编代码的样子:
#include <stdio.h>
int main(){
for(int i = 0; i < 10; i++){
printf("%d\n", i);
}
return 0;
}
运行此代码时,我得到当前输出:
.text
.globl _main
loop0.0:
movl -4(%rbp), %eax #eax = i
cmpl $10, %eax #compare i with 10
jg loop0.2 #if 10 > i goto loop0.2
loop0.1:
leaq _format(%rip), %rdi #set arg1 to format
movl -4(%rbp), %esi #set arg2 to i
call _printf #printf(format, i)
movl -4(%rbp), %esi #set esi to i
addl $1, %esi #esi++
movl %esi, -4(%rbp) #i = esi
jmp loop0.0
_main: #int main
pushq %rbp
movq %rsp, %rbp
movl $0, -4(%rbp) #i = 0
jmp loop0.0 #goto loop0.0
loop0.2:
xor %eax, %eax #return 0;
popq %rbp
retq
.data
_format:
.asciz "%d\n"
以此类推
为什么我的代码先显示0
2
2
2
2
2
2
(应显示),然后无限显示两次?我希望我的注释是正确的,因为这是我认为每一行代码所做的。
答案 0 :(得分:3)
Main不会为i分配堆栈空间,因此对printf的调用将覆盖i。
添加说明
sub $16, %rsp
紧接着
mov %rsp, %rbp
并添加
add $16, %rsp
就在
之前pop %rbp
减去16而不是4的原因是为了保持堆栈对齐。
答案 1 :(得分:2)
不要将i
保留在被call
阻塞的红色区域中(请参阅@prl的答案),将i
保留在寄存器中。
您似乎正在遵循(可怕的)反优化编译器输出样式,该输出将所有内容存储到内存中进行调试。
在函数中保存/恢复rbx
,并将ebx
用于i
。 (要在call _printf
之前保持16字节的堆栈对齐,请不要制作堆栈帧,因为您不需要为本地人使用任何堆栈空间。)
顺便说一句,这没错,但是在函数入口点之前放置一些函数体(您的循环)是非常不常规的。通常,您的代码过于复杂。这就像您从针对C函数的优化编译器中获得的东西一样。 (我没有检查https://godbolt.org/,但建议您看看。)
_main: #int main
push %rbx # save RBX and realign the stack by 16
xor %ebx, %ebx
.loop: # do {
mov %ebx, %esi
lea _format(%rip), %rdi
xor %eax,%eax # %al = 0 FP args in XMM registers
call _printf # printf(format, i)
inc %ebx # i++
cmp $10, %ebx
jl .loop # }while(i<10)
xor %eax, %eax #return 0;
pop %rbx
ret
# Read-only data can go in .rodata
# only mutable static data needs to go in .data
.section .rodata
_format: .asciz "%d\n"