我必须翻译以下简单的C代码:
int add(int a, int b);
int main()
{
int a,b;
a = 0;
while(a<5)
{
a++;
printi(a);
prints("\n");
}
return 0;
}
int add(int a, int b)
{
char cx = 'a';
int x = a-b;
return x;
}
我已经制作了一个编译器,将其转换为以下GNU x86汇编代码。 (printi和print是我翻译后链接的库函数。)
.section .rodata
.LC0:
.string "\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
movl $0, -4(%ebp)
movl -4(%ebp), %eax
movl %eax, -12(%ebp)
.L0:
movl $5, %eax
movl -4(%ebp), %edx
cmpl %edx, %eax
jge .CH1
.CH0:
movl $1, -16(%ebp)
jmp .CH2
.CH1:
movl $0, -16(%ebp)
.CH2:
movl $0, %eax
cmpl -16(%ebp), %eax
je .L2
jmp .L1
.L1:
movl -4(%ebp), %eax
movl %eax, -20(%ebp)
movl -20(%ebp), %eax
movl $1, %edx
addl %edx, %eax
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
movl %eax, (%esp)
call printi
movl %eax, -24(%ebp)
movl $.LC0, (%esp)
call prints
movl %eax, -28(%ebp)
jmp .L0
.L2:
movl $0, %eax
leave
ret
.size main, .-main
.globl add
.type add, @function
add:
pushl %ebp
movl %esp, %ebp
movb $97, -1(%ebp)
movl 4(%ebp), %eax
movl 8(%ebp), %edx
subl %edx, %eax
movl %eax, -9(%ebp)
movl -9(%ebp), %eax
movl %eax, -5(%ebp)
movl -5(%ebp), %eax
leave
ret
.size add, .-add
但该程序不输出任何内容。看来我在while的检查表达式附近犯了一个错误。
指令cmpl %edx, %eax
应将标志设置为0-5,即-5。因此,jge不应将其分支到.CH1。因此-16(%ebp)
应该设置为1,然后它应该进入.CH2。当1!= 0时,它应该进入L1。我不知道我哪里出错了。
答案 0 :(得分:1)
指令
cmpl %edx, %eax
应将标志设置为0-5,即-5。 Ĵ
不。请记住,在AT&amp; T语法中,操作数顺序为source, destination
。您有eax = 5
和edx = 0
,因此cmpl %edx, %eax
会根据5-0设置标记,之后jge
应跳转。< / p>