I've been looking for hours, and i can't find the mistake in my code. The program seems to exit at the "opadd" tag. I am using x86_64 on Linux, with AT&T syntax.
The program takes as input a string of characters, for example, "2 3 add 4 mul", and then, for this particular example, should do as follows:
.data
formatPrintf: .asciz "%d"
sir: .space 1000
delim: .asciz " "
formatScanf: .asciz "%1000[^\n]"
cuvant: .space 100
primulNumar: .space 4
atoiCuvant: .long 0
x: .space 4
y: .space 4
eval: .long 0
op: .space 4
add: .asciz "add"
sub: .asciz "sub"
mul: .asciz "mul"
div: .asciz "div"
.text
.global main
main:
pushl $sir
pushl $formatScanf
call scanf
popl %ebx
popl %ebx
pushl $delim
pushl $sir
call strtok
popl %ebx
popl %ebx
pushl %eax
call atoi
popl primulNumar
movl %eax, primulNumar
pushl primulNumar
et_loop:
pushl $delim
pushl $0
call strtok
popl %ebx
popl %ebx
cmp $0, %eax
je exit
mov %eax, cuvant
pushl %eax
call atoi
popl %ebx
mov %eax, atoiCuvant
cmp $0, atoiCuvant
je operatie
pushl %eax
jmp et_loop
operatie:
push $cuvant
push $add
call strcmp
popl %ebx
popl %ebx
cmp $0, %eax
je opadd
push $cuvant
push $sub
call strcmp
popl %ebx
popl %ebx
cmp $0, %eax
je opsub
push $cuvant
push $mul
call strcmp
popl %ebx
popl %ebx
cmp $0, %eax
je opmul
push $cuvant
push $div
call strcmp
popl %ebx
popl %ebx
cmp $0, %eax
je opdiv
opadd:
popl %edx
popl y
add %edx, y
push y
jmp et_loop
opmul:
popl %eax
popl %ebx
mul %ebx
pushl %eax
jmp et_loop
opdiv:
popl %eax
popl %ebx
div %ebx
pushl %eax
jmp et_loop
opsub:
popl %eax
popl y
sub %eax,y
pushl y
jmp et_loop
exit:
popl eval
pushl eval
pushl $formatPrintf
call printf
popl %ebx
popl %ebx
pushl $0
call fflush
popl %ebx
movl $1, %eax
xorl %ebx, %ebx
int $0x80
opadd:
popl %edx <-- there IS a push without a pop on the first line of code, but...
popl y <-- now there is nothing left in the stack
It doesn't seem like there is anything left in the stack when you get to opadd
. Every push
operation in et_loop
and operatie
has a corresponding pop
. I cannot test your example yet, as you didn't include your .data
section, but I'm almost sure that this is the problem.
mov %eax, cuvant pushl %eax call atoi popl %ebx
Knowing that atoi
espects a pointer, we see that the cuvant variable will hold an address.
operatie: push $cuvant push $add call strcmp popl %ebx popl %ebx
Knowing that strcmp
expects two pointers, we see that this code passes the address of the cuvant variable where in fact it should pass the address that is contained in the cuvant variable (pointing at the current token).
Therefore all comparing in operatie will fail.
cmp $0, %eax je opdiv opadd:
When all 4 compares fail the code just falls through in opadd:
. Nothing good to be expected from that!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.