[section .bss] state: resd 2 buffer: resb 0x100000 [section .data] p: dd buffer + 1 [section .rodata] printFormat: scanFormat: db "%lf",10,0 error: db "error",10,0 [section .text] extern sscanf, getchar, printf %macro ifnspace 1 cmp eax, 32 je %%skip cmp eax, 9 jne %1 %%skip: %endmacro %macro ifspace 1 cmp eax, 32 je %1 cmp eax, 9 je %1 %endmacro %macro sethandler 1 mov [state], esp mov dword [state + 4], %1 %endmacro %macro longret 0 mov esp, [state] jmp [state + 4] %endmacro eval: sub esp, 12 .next: sub ebx, 1 movsx eax, byte [ebx] ifnspace .found cmp ebx, buffer jg .next .error: longret .found: cmp byte [ebx], '+' je .add cmp byte [ebx], '-' je .sub cmp byte [ebx], '*' je near .mul cmp byte [ebx], '/' je near .div .skip: sub ebx, 1 movsx eax, byte [ebx] ifnspace .skip add ebx, 1 lea eax, [esp] mov [esp + 8], eax mov eax, scanFormat mov [esp + 4], eax mov [esp], ebx call sscanf cmp eax, 0 je .error fld qword [esp] add esp, 12 ret %macro operandhandler 1 .%1: call eval ; pop value fstp qword [esp] call eval fld qword [esp] f%1p st1, st0 add esp, 12 ret %endmacro operandhandler add operandhandler sub operandhandler mul operandhandler div global main main: sub esp, 12 mov byte [buffer], ' ' sethandler .error mov ebx, [p] .scanloop: call getchar cmp eax, -1 je near .exit cmp eax, 10 je .calc cmp eax, 13 je .calc mov [ebx], al add ebx, 1 jmp short .scanloop .calc: sub ebx, 1 cmp ebx, buffer jle near .tonext movsx eax, byte [ebx] ifspace .calc add ebx, 1 mov byte [ebx], ' ' add ebx, 1 call eval .getend: sub ebx, 1 cmp ebx, buffer jle .print movsx eax, byte [ebx] ifspace .getend .print: cmp ebx, buffer jne .error fstp qword [esp + 4] mov eax, printFormat mov [esp], eax call printf jmp short .tonext .error: fstp qword [esp + 4] mov eax, error mov [esp], eax call printf .tonext: mov eax, buffer add eax, 1 mov ebx, eax jmp .scanloop .exit: add esp, 12 ret