나는 다음과 같은 간단한 C 코드를 번역 할 수 있습니다cmpl 및 jge이 같은 exected 작동하지 않는, 86
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의 check 식을 중심으로 어딘가에서 실수를 한 것으로 보인다.
명령어 cmpl %edx, %eax
은 플래그를 0-5로 설정해야합니다 (-5). 따라서 jge는 .CH1로 분기하지 않아야합니다. 따라서 -16(%ebp)
은 1로 설정해야하며 .CH2로 가져와야합니다. 1! = 0이므로, L1으로 들어가야합니다. 내가 어디로 잘못 가고 있는지 모르겠다.
오, 젠장! 다시는. 고마워. – arkanath