/* architeture independent */

_lib << "imprima:\n"
        "  %define vargc ebp+8\n"
        "\n"
        "  %define i ebp-4\n"
        "  begin 4\n"
        "\n"
        "  mov dword [i], 0\n"
        "  .while:\n"
        "    mov ebx, dword [vargc]\n"
        "    mov ecx, dword [i]\n"
        "    cmp ecx, ebx\n"
        "    jge near .endwhile\n"
        "\n"
        "    mov eax, dword [vargc]\n"
        "    sub eax, dword [i]\n"
        "    mov ebx, 8\n"
        "    mul ebx\n"
        "\n"
        "    add eax, 8\n"
        "\n"
        "    mov ebx, dword [ebp+eax-4] \n"
        "    mov edx, dword [ebp+eax]   \n"
        "\n"
        "    cmp ebx, 'i'\n"
        "    je .imp_inteiro\n"
        "\n"
        "    cmp ebx, 'r'\n"
        "    je .imp_real\n"
        "\n"
        "    cmp ebx, 'c'\n"
        "    je .imp_caractere\n"
        "    \n"
        "    cmp ebx, 's'\n"
        "    je .imp_literal\n"
        "    \n"
        "    cmp ebx, 'l'\n"
        "    je .imp_logico\n"
        "    \n"
        "    jmp .footer\n"
        "\n"
        "      .imp_inteiro:\n"
        "        addarg edx\n"
        "        call imprima_inteiro\n"
        "        clargs 1\n"
        "        jmp .footer\n"
        "\n"
        "      .imp_real:\n"
        "        addarg edx\n"
        "        call imprima_real\n"
        "        clargs 1\n"
        "        jmp .footer\n"
        "  \n"
        "      .imp_caractere:\n"
        "        addarg edx\n"
        "        call imprima_caractere\n"
        "        clargs 1\n"
        "        jmp .footer\n"
        "  \n"
        "      .imp_literal:\n"
        "        addarg edx\n"
        "        call imprima_literal\n"
        "        clargs 1\n"
        "        jmp .footer\n"
        "  \n"
        "      .imp_logico:\n"
        "        addarg edx\n"
        "        call imprima_logico\n"
        "        clargs 1\n"
        "\n"
        "    .footer:\n"
        "      inc dword [i]\n"
        "      jmp .while\n"
        "  .endwhile:\n"
        "\n"
        "  return\n"
        "  %undef vargc\n"
        "  %undef i\n"
        "\n"
        "imprima_literal:\n"
        "    %define string ebp+8\n"
        "    begin 0\n"
        "\n"
        "    mov eax, [string]\n"
        "    cmp eax, ''\n"
        "    jz .imprima_nulo\n"
        "\n"
        "    addarg dword [string]\n"
        "    call print\n"
        "    clargs 1\n"
        "    jmp .end\n"
        "\n"
        "    .imprima_nulo"
        "      addarg dword str_null\n"
        "      call print\n"
        "      clargs 1\n"
        "\n"
        "    .end:\n"
        "      return\n"
        "    %undef string\n"
        "\n"
        "imprima_inteiro:    \n"
        "    %define num ebp+8    \n"
        "\n"
        "    %define buffer   ebp-BUFFER_SIZE\n"
        "    begin BUFFER_SIZE\n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg dword [num]    \n"
        "    call itoa\n"
        "    clargs 2\n"
        "\n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    call print\n"
        "    clargs 1\n"
        "\n"
        "    return\n"
        "    %undef num\n"
        "    %undef buffer\n"
        "\n"
        "imprima_real:    \n"
        "    %define num ebp+8\n"
        "    \n"
        "    %define buffer   ebp-BUFFER_SIZE\n"
        "    begin BUFFER_SIZE\n"
        "\n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg dword [num]    \n"
        "    call ftoa\n"
        "    clargs 2\n"
        "\n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    call print\n"
        "    clargs 1\n"
        "\n"
        "    return\n"
        "    %undef num\n"
        "    %undef buffer  \n"
        "\n"
        "print_c:    \n"
        "    %define carac ebp+8\n"
        "\n"
        "    begin 0\n"
        "\n"
        "    lea eax, [carac]\n"
        "    addarg eax\n"
        "    call print\n"
        "    clargs 1\n"
        "\n"
        "    return\n"
        "    %undef carac\n"
        "\n"
        "imprima_caractere:\n"
        "    \n"
        "    %define carac ebp+8\n"
        "    begin 4\n"
        "    \n"
        "    addarg dword [carac]\n"
        "    call print_c\n"
        "    clargs 1\n"
        "    \n"
        "    return\n"
        "    %undef carac\n"
        "\n"
        "imprima_logico:    \n"
        "    %define val ebp+8\n"
        "\n"
        "    begin 0\n"
        "\n"
        "    mov eax, [val]\n"
        "    cmp eax, 0\n"
        "    jz .false\n"
        "    mov eax, str_true\n"
        "    jmp .print\n"
        "\n"
        "    .false:\n"
        "      mov eax, str_false\n"
        "\n"
        "    .print:\n"
        "      addarg eax\n"
        "      call print\n"
        "      clargs 1\n"
        "\n"
        "    return\n"
        "    %undef val\n"
        "\n"
        "strpos:    \n"
        "    %define string ebp+12\n"
        "    %define carac  ebp+8\n"
        "\n"
        "    begin 0\n"
        "\n"
        "    mov eax, [string]\n"
        "    cmp eax, 0\n"
        "    jnz .calc\n"
        "\n"
        "    mov eax, 0\n"
        "    return\n"
        "\n"
        "    .calc:\n"
        "      mov eax, 0\n"
        "      .do:\n"
        "        mov ebx, [string]\n"
        "        mov ecx, [carac]\n"
        "        cmp [ebx+eax], cl\n"
        "        jz  .break\n"
        "\n"
        "        cmp [ebx+eax], byte 0\n"
        "        jz .notfound\n"
        "\n"
        "        inc eax\n"
        "        jnz .do\n"
        "      .break:\n"
        "\n"
        "    return\n"
        "\n"
        "    .notfound:\n"
        "      mov eax, -1\n"
        "      return\n"
        "\n"
        "    %undef string\n"
        "    %undef carac\n"
        "\n"
        "strlen:    \n"
        "    %define string ebp+8\n"
        "\n"
        "    begin 0\n"
        "\n"
        "    addarg dword [string]\n"
        "    addarg 0\n"
        "    call strpos\n"
        "    clargs 2\n"
        "\n"
        "    return\n"
        "\n"
        "     %undef string\n"
        "\n"
        "is_num:    \n"
        "    %define carac ebp+8\n"
        "\n"
        "    begin 0\n"
        "\n"
        "    cmp byte  [carac], 48\n"
        "    jl .false\n"
        "\n"
        "    cmp byte [carac], 57\n"
        "    jg .false\n"
        "\n"
        "    mov eax, 1\n"
        "    return\n"
        "\n"
        "    .false:\n"
        "      mov eax, 0\n"
        "      return\n"
        "\n"
        "     %undef carac\n"
        "\n"
        "atoi:    \n"
        "    %define string ebp+8  \n"
        "    \n"
        "    %define num   ebp-4\n"
        "    %define m     ebp-8\n"
        "    %define i     ebp-12\n"
        "    %define len   ebp-16\n"
        "    %define negt  ebp-20\n"
        "    begin 20\n"
        "  \n"
        "    mov dword [num], 0\n"
        "    mov dword [m], 1\n"
        "    mov dword [negt], 0\n"
        "  \n"
        "    addarg dword [string]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    cmp eax, dword 0\n"
        "    jz near .ret_zero\n"
        "\n"
        "    mov dword [len], eax\n"
        "    mov dword [i], 0\n"
        "\n"
        "    \n"
        "    %define minus_sig 45 \n"
        "    %define plus_sig 43\n"
        "    mov eax, [string]\n"
        "    xor ebx, ebx\n"
        "    mov bl, [eax]\n"
        "\n"
        "    cmp ebx, minus_sig\n"
        "    jz .negative\n"
        "\n"
        "    cmp ebx, plus_sig\n"
        "    jz .positive\n"
        "\n"
        "    jmp .conv\n"
        "\n"
        "    .negative:\n"
        "      mov dword [negt], 1\n"
        "      mov eax, [string]\n"
        "      inc eax\n"
        "      mov [string], eax\n"
        "      jmp .conv\n"
        "\n"
        "    .positive:\n"
        "      mov dword [negt], 0\n"
        "      mov eax, [string]\n"
        "      inc eax\n"
        "      mov [string], eax\n"
        "\n"
        "  .conv:\n"
        "\n"
        "    mov eax, [len]\n"
        "    .while:\n"
        "      mov eax, dword [i]\n"
        "      cmp eax, [len]\n"
        "      jg .endwhile      \n"
        "      \n"
        "      mov ebx, [string]\n"
        "      mov ecx, [i]        \n"
        "      xor edx, edx\n"
        "      mov dl, [ebx+ecx]      \n"
        "\n"
        "      addarg edx\n"
        "      call is_num\n"
        "      clargs 1\n"
        "  \n"
        "      cmp eax, 0\n"
        "      jz .endwhile\n"
        "  \n"
        "      inc dword [i]\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "  \n"
        "    cmp dword [i], 0\n"
        "    jz .ret_zero\n"
        "  \n"
        "\n"
        "    dec dword [i]    \n"
        "    \n"
        "    .while2:\n"
        "      cmp dword [i], 0\n"
        "      jl .endwhile2\n"
        "\n"
        "      \n"
        "      mov ebx, [string]\n"
        "      mov ecx, [i]\n"
        "      xor eax, eax\n"
        "      mov al, byte [ebx+ecx]\n"
        "\n"
        "      \n"
        "      sub al, 48\n"
        "\n"
        "      mul dword [m]      \n"
        "\n"
        "      \n"
        "      add [num], eax\n"
        "\n"
        "      dec dword [i]\n"
        "\n"
        "      \n"
        "      mov eax, [m]\n"
        "      mov ebx, 10\n"
        "      mul ebx\n"
        "      mov [m], eax\n"
        "\n"
        "      jmp .while2\n"
        "    .endwhile2:\n"
        "  \n"
        "    cmp dword [negt], 1\n"
        "    jnz .return_pos\n"
        "\n"
        "    mov eax, [num]\n"
        "    neg eax\n"
        "    return\n"
        "   \n"
        "    .return_pos:\n"
        "      mov eax, [num]\n"
        "      return\n"
        "\n"
        "    .ret_zero:\n"
        "      mov eax, 0\n"
        "      return\n"
        "\n"
        "    %undef minus_sig\n"
        "    %undef plus_sig\n"
        "    %undef string    \n"
        "    %undef num\n"
        "    %undef m\n"
        "    %undef i\n"
        "    %undef len\n"
        "    %undef negt\n"
        "\n"

        "atof:\n"
        "    %define string ebp+8\n"
        "    \n"
        "    %define i        ebp-4\n"
        "    %define dot      ebp-8\n"
        "    %define len      ebp-12\n"
        "    %define declen   ebp-16\n"
        "    %define power    ebp-20\n"
        "    %define integral ebp-24\n"
        "    %define decimal  ebp-28\n"
        "    %define float    ebp-32\n"
        "    %define sign     ebp-36\n"
        "\n"
        "    begin 36\n"
        "\n"
        "    mov dword [dot], -1\n"
        "    mov dword [float], 0\n"
        "    mov dword [sign], 0\n"
        "        \n"
        "    addarg dword [string]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    mov dword [len], eax\n"
        "\n"
        "    addarg dword [string]\n"
        "    call atoi\n"
        "    clargs 1\n"
        "    \n"
        "    mov dword [integral], eax\n"
        "\n"
        "    finit\n"
        "    fild dword [integral]\n"
        "    fstp dword [float]\n"
        "\n"
        "    mov dword [i], 0\n"
        "    .while:\n"
        "      mov eax, dword [i]\n"
        "      cmp eax, dword [len]\n"
        "      jge .endwhile\n"
        "\n"
        "      mov eax, dword [string]\n"
        "      add eax, dword [i]\n"
        "      \n"
        "      mov bl, byte [eax]\n"
        "\n"
        "      cmp bl, '.'\n"
        "      je .dot_found\n"
        "\n"
        "      cmp bl, '+'\n"
        "      je .footer\n"
        "      cmp bl, '-'\n"
        "      je .neg_footer\n"
        "\n"
        "      addarg ebx\n"
        "      call is_num\n"
        "      clargs 1\n"
        "      cmp eax, 1\n"
        "      jz .footer\n"
        "\n"
        "      mov eax, dword [i]\n"
        "      mov dword [len], eax\n"
        "      jmp .endwhile\n"
        "\n"
        "      .dot_found:\n"
        "        mov eax, dword [i]\n"
        "        mov dword [dot], eax\n"
        "        jmp .footer\n"
        "        \n"
        "      .neg_footer:\n"
        "        mov dword [sign], 1        \n"
        "      .footer:\n"
        "        inc dword [i]\n"
        "        jmp .while\n"
        "    .endwhile:\n"
        "\n"
        "    cmp dword [dot], -1\n"
        "    jnz .endif\n"
        "      jmp .end\n"
        "    .endif:\n"
        "    \n"
        "    inc dword [dot]\n"
        "\n"
        "    mov eax, dword [string]\n"
        "    mov ebx, dword [dot]\n"
        "    add eax, ebx\n"
        "\n"
        "    addarg eax\n"
        "    call atoi\n"
        "    clargs 1\n"
        "\n"
        "    mov dword [decimal], eax\n"
        "\n"
        "    mov eax, dword [len]\n"
        "    sub eax, dword [dot]\n"
        "\n"
        "    mov dword [declen], eax    \n"
        " \n"
        "    addarg 10\n"
        "    addarg dword [declen]\n"
        "    call pow\n"
        "    clargs 2\n"
        "\n"
        "    mov dword [power], eax\n"
        "\n"
        "    fild dword [decimal]\n"
        "    fidiv dword [power]\n"
        "    fstp dword [decimal]\n"
        "    fld dword [float]\n"
        "\n"
        "    cmp dword [sign], 0 \n"
        "    je .pos\n"
        "      fsub dword [decimal]\n"
        "      jmp .endif2\n"
        "    .pos:\n"
        "      fadd dword [decimal]\n"
        "    .endif2:\n"
        "      fstp dword [float]\n"
        "\n"
        "    .end:\n"
        "      mov eax, dword [float]\n"
        "      return\n"
        "\n"
        "    %undef string\n"
        "    %undef i\n"
        "    %undef dot\n"
        "    %undef len\n"
        "    %undef declen\n"
        "    %undef power\n"
        "    %undef integral\n"
        "    %undef decimal\n"
        "    %undef float\n"
        "    %undef sign\n"
        "\n"

        "itoa:    \n"
        "    %define buffer ebp+12\n"
        "    %define num ebp+8\n"
        "    \n"
        "    %define sig ebp-4\n"
        "    begin 4\n"
        "\n"
        "    \n"
        "    mov eax, [num]\n"
        "    mov [sig], eax\n"
        "    shr eax, 31\n"
        "    mov [sig], eax    \n"
        "\n"
        "    cmp [sig], dword 0\n"
        "    jz .endif\n"
        "      neg dword [num]\n"
        "    .endif:\n"
        "\n"
        "    \n"
        "    mov ecx, 0\n"
        "    mov eax, [num] \n"
        "    .trans:\n"
        "      mov ebx, 10\n"
        "      mov edx, 0\n"
        "      idiv ebx   \n"
        "      add edx, byte 48\n"
        "      push edx\n"
        "      inc ecx \n"
        "    cmp eax, 0\n"
        "    jnz .trans\n"
        "\n"
        "    \n"
        "    cmp [sig], dword 0\n"
        "    jz .else1\n"
        "      %define minus_sig 45\n"
        "      mov edx, 1 \n"
        "      mov eax, [buffer]\n"
        "      mov [eax], byte minus_sig            \n"
        "      jmp .endif1\n"
        "    .else1:\n"
        "      mov edx, 0 \n"
        "    .endif1:\n"
        "    \n"
        "    .reorder:\n"
        "      pop eax\n"
        "      mov ebx, [buffer]\n"
        "      mov [ebx+edx], eax \n"
        "      dec ecx \n"
        "      inc edx \n"
        "    cmp ecx, 0 \n"
        "    jnz .reorder\n"
        "\n"
        "    return\n"
        "\n"
        "    %undef buffer\n"
        "    %undef num\n"
        "    \n"
        "    %undef sig\n"
        "    %undef minus_sig\n"
        "\n"
        "ftoa:\n"
        "    %define BIAS 127\n"
        "    \n"
        "    %define buffer ebp+12\n"
        "    %define num ebp+8\n"
        "    \n"
        "    %define exp    ebp-4\n"
        "    %define mant   ebp-8\n"
        "    %define left   ebp-12\n"
        "    %define sig    ebp-16    \n"
        "    %define offset ebp-20\n"
        "    %define r      ebp-24\n"
        "    %define term   ebp-28\n"
        "    %define acc    ebp-32\n"
        "    %define tmp    ebp-36\n"
        "    %define right  ebp-40\n"
        "    \n"
        "    %define lst    40    \n"
        "  \n"
        "    begin lst\n"
        "    \n"
        "    mov eax, [num]\n"
        "    mov [sig], eax\n"
        "    shr eax, 31\n"
        "    mov [sig], eax\n"
        "\n"
        "    \n"
        "    mov eax, [num]\n"
        "    and eax, 0x7FFFFFFF\n"
        "    mov [num], eax\n"
        "\n"
        "    \n"
        "    mov eax, [num]\n"
        "    shr eax, 23\n"
        "    mov [exp], eax\n"
        "\n"
        "    \n"
        "    mov eax, [num]\n"
        "    and eax, 0x7FFFFF\n"
        "    mov [mant], eax\n"
        "    \n"
        "    mov eax, [exp]      \n"
        "    mov ebx, [mant]\n"
        "    or eax, ebx\n"
        "      cmp eax, 0\n"
        "      jnz .endif\n"
        "      mov eax, dword [buffer]\n"
        "      mov dword [eax], 0x30302E30\n"
        "      mov dword [eax+4], 0x0\n"
        "      jmp .end\n"
        "    .endif:\n"
        "    \n"
        "    sub [exp], dword BIAS  \n"
        "    \n"
        "    or [mant], dword 0x800000    \n"
        "    \n"
        "    mov eax, 25\n"
        "    sub eax, [exp]\n"
        "      cmp eax, 32\n"
        "      jg .else1   \n"
        "      mov eax, [mant]\n"
        "      mov ecx, 23\n"
        "      sub ecx, [exp]\n"
        "      shr eax, cl\n"
        "      mov [left], eax\n"
        "      jmp .endif1\n"
        "    .else1:\n"
        "      mov [left], dword 0\n"
        "    .endif1:\n"
        "    \n"
        "    \n"
        "    mov eax, 9\n"
        "    add eax, [exp]\n"
        "      cmp eax, 0\n"
        "      jl .else2\n"
        "      mov ecx, 9\n"
        "      add ecx, [exp]\n"
        "      mov eax, [mant]\n"
        "      shl eax, cl\n"
        "      mov [mant], eax\n"
        "      jmp .endif2\n"
        "    .else2:\n"
        "      mov ecx, [exp]\n"
        "      sub ecx, 9\n"
        "      mov eax, [mant]\n"
        "      shr eax, cl          \n"
        "    .endif2:\n"
        "\n"
        "    mov [offset], dword 31\n"
        "    \n"
        "    mov eax, [mant]\n"
        "    mov [r], eax\n"
        "    \n"
        "    mov [term], dword 1\n"
        "    \n"
        "    mov [acc], dword 0\n"
        "\n"
        "    finit\n"
        "    \n"
        "    .while:    \n"
        "      mov eax, [offset]\n"
        "      cmp eax, 1\n"
        "      jz .endwhile\n"
        "  \n"
        "      \n"
        "      mov eax, [r]\n"
        "      mov ecx, [offset]\n"
        "      shr eax, cl\n"
        "      and eax, 1\n"
        "        cmp eax, 0\n"
        "        jz .endif3\n"
        "  \n"
        "        \n"
        "        mov eax, 2\n"
        "        mov ebx, [term]\n"
        "        neg ebx\n"
        "\n"
        "        addarg eax\n"
        "        addarg ebx\n"
        "        call pow \n"
        "        clargs 2\n"
        "\n"
        "        mov [tmp], eax\n"
        "  \n"
        "        fld  dword [acc] \n"
        "        fadd dword [tmp]\n"
        "        fstp dword [acc]\n"
        "      .endif3:\n"
        "      \n"
        "      inc dword [term]\n"
        "      \n"
        "      dec dword [offset]\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "\n"
        "    fninit\n"
        "    \n"
        "    fld dword [acc] \n"
        "    mov [tmp], dword 100\n"
        "    fimul dword [tmp]\n"
        "    \n"
        "    frndint\n"
        "    \n"
        "    fist dword [acc]\n"
        "\n"
        "    mov eax, [acc]\n"
        "    mov [right], eax\n"
        "\n"
        "    cmp [sig], dword 0\n"
        "    jz .endif5\n"
        "      neg dword [left]\n"
        "    .endif5:\n"
        "\n"
        "    addarg dword [buffer]\n"
        "    addarg dword [left]\n"
        "    call itoa\n"
        "    clargs 2    \n"
        "    \n"
        "    addarg dword [buffer]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    add eax, dword [buffer]\n"
        "    mov [eax], byte '.'\n"
        "    inc eax\n"
        "    mov [tmp], eax\n"
        "    \n"
        "    %define buffer2 ebp-lst+4\n"
        "    %define bfsize  1024\n"
        "    sub  esp, bfsize\n"
        "\n"
        "    addarg dword [buffer2]\n"
        "    addarg dword [right]\n"
        "    call itoa\n"
        "    clargs 2\n"
        "    \n"
        "\n"
        "    addarg dword [buffer2]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    \n"
        "    cmp eax, 2\n"
        "    jz .endif4\n"
        "      %define zero 48\n"
        "      xor eax, eax\n"
        "      mov ebx, [buffer2]\n"
        "      mov al, [ebx]\n"
        "      mov [ebx], byte zero\n"
        "      mov byte [ebx+1], al\n"
        "    .endif4:\n"
        "\n"
        "    mov eax, [buffer2]\n"
        "    mov ebx, [tmp]\n"
        "    .append:\n"
        "      cmp [eax], byte 0\n"
        "      jz .endappend\n"
        "      \n"
        "      xor ecx, ecx\n"
        "      mov cl, [eax]\n"
        "      mov [ebx], cl\n"
        "      inc eax\n"
        "      inc ebx\n"
        "      jmp .append\n"
        "    .endappend:\n"
        "\n"
        "    mov [ebx], byte 0\n"
        "\n"
        "  .end:\n"
        "    return\n"
        "\n"
        "    %undef BIAS\n"
        "    \n"
        "    %undef buffer\n"
        "    %undef num\n"
        "    \n"
        "    %undef  exp\n"
        "    %undef  mant\n"
        "    %undef  left\n"
        "    %undef  sig\n"
        "    %undef  offset\n"
        "    %undef  r\n"
        "    %undef  term\n"
        "    %undef  acc\n"
        "    %undef  tmp\n"
        "    %undef  right    \n"
        "    %undef  lst\n"
        "\n"
        "    %undef buffer2\n"
        "    %undef bfsize\n"
        "    %undef zero\n"
        "\n"
        "pow:    \n"
        "    %define base ebp+12\n"
        "    %define exp  ebp+8\n"
        "    \n"
        "    %define res  ebp-4\n"
        "    %define i    ebp-8\n"
        "    %define sig  ebp-12\n"
        "    %define tmp  ebp-16\n"
        "    begin 14\n"
        "    \n"
        "    mov eax, [exp]\n"
        "    mov ecx, 31\n"
        "    shr eax, cl\n"
        "    mov [sig], eax\n"
        "    \n"
        "    mov eax, [sig]\n"
        "    cmp eax, 0\n"
        "    jz .endif\n"
        "      mov eax, [exp]\n"
        "      neg eax\n"
        "      mov [exp], eax\n"
        "    .endif:\n"
        "    \n"
        "    mov [res], dword 1\n"
        "    \n"
        "    mov [i], dword 0\n"
        "    .while:\n"
        "      mov eax, [i]\n"
        "      cmp eax, [exp]\n"
        "      jge .endwhile\n"
        "      \n"
        "      mov eax, [res]\n"
        "      mul dword [base]\n"
        "      mov [res], eax\n"
        "      \n"
        "      inc dword [i]\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "    \n"
        "    cmp [sig], dword 0\n"
        "    jz .noneg\n"
        "    .negative:\n"
        "      fninit\n"
        "      mov [tmp], dword 0x3F800000 \n"
        "  \n"
        "      fld   dword [tmp]\n"
        "      fidiv dword [res]\n"
        "      fstp  dword [res]\n"
        "    .noneg:\n"
        "\n"
        "    mov eax, [res]\n"
        "\n"
        "    return\n"
        "\n"
        "    %undef base\n"
        "    %undef exp\n"
        "    \n"
        "    %undef res\n"
        "    %undef i\n"
        "    %undef sig\n"
        "    %undef tmp\n"
        "\n"
        "matrix_init:    \n"
        "    %define matrix      ebp+12\n"
        "    %define msize       ebp+8\n"
        "\n"
        "    begin 0\n"
        "  \n"
        "    mov eax, 0\n"
        "    .while:\n"
        "      cmp eax, [msize]\n"
        "      jge .endwhile\n"
        "      mov ecx, [matrix]\n"
        "      add ecx, eax\n"
        "      mov [ecx], byte 0\n"
        "      inc eax\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "\n"
        "    return\n"
        "\n"
        "    %undef matrix\n"
        "    %undef msize\n"
        "\n"
        "matrix_cpy:\n"
        "    %define src       ebp+20\n"
        "    %define dest      ebp+16\n"
        "    %define is_string ebp+12\n"
        "    %define msize     ebp+8\n"
        "    begin 0\n"
        "\n"
        "    mov eax, 0\n"
        "    .while:\n"
        "      cmp eax, [msize]\n"
        "      jge .endwhile\n"
        "\n"
        "      mov ebx, [src]\n"
        "      add ebx, eax\n"
        "      xor ecx, ecx\n"
        "      mov cl, [ebx]\n"
        "\n"
        "      mov ebx, [dest]\n"
        "      add ebx, eax\n"
        "\n"
        "      mov [ebx], cl\n"
        "\n"
        "      inc eax\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "\n"
        "    return\n"
        "\n"
        "    %undef src\n"
        "    %undef dest\n"
        "    %undef is_string\n"
        "    %undef msize\n"
        "\n"
        "strcpy:    \n"
        "    %define src    ebp+12\n"
        "    %define dest   ebp+8\n"
        "    \n"
        "    %define src_len     ebp-4\n"
        "    begin 4\n"
        "\n"
        "    addarg dword [src]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    mov [src_len], eax\n"
        "\n"
        "    cmp eax, [src_len]\n"
        "    jnz .end\n"
        "    \n"
        "    mov eax, 0\n"
        "    mov edx, [dest]\n"
        "    .while:\n"
        "      cmp eax, [src_len]\n"
        "      jge .endwhile\n"
        "\n"
        "      mov ebx, [src]\n"
        "      xor ecx, ecx\n"
        "      mov cl, [ebx+eax]\n"
        "\n"
        "      mov [edx+eax], cl\n"
        "\n"
        "      inc eax\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "\n"
        "    mov [edx+eax], byte 0\n"
        "\n"
        "    .end:\n"
        "      return\n"
        "\n"
        "    %undef src\n"
        "    %undef dest    \n"
        "    %undef src_len\n"
        "\n"
        "strcmp:    \n"
        "    %define left    ebp+12\n"
        "    %define right   ebp+8\n"
        "\n"
        "    \n"
        "    %define left_len     ebp-4\n"
        "    %define l            ebp-8\n"
        "    %define r            ebp-12\n"
        "    begin 12\n"
        "\n"
        "    addarg dword [left]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    mov [left_len], eax\n"
        "\n"
        "    addarg dword [right]\n"
        "    call strlen\n"
        "    clargs 1\n"
        "\n"
        "    cmp eax, [left_len]\n"
        "    jnz .false\n"
        "\n"
        "    mov eax, 0\n"
        "    .while:\n"
        "      cmp eax, [left_len]\n"
        "      jge .endwhile\n"
        "\n"
        "      mov ebx, [left]\n"
        "      xor edx, edx\n"
        "      mov dl, [ebx+eax]\n"
        "\n"
        "      mov ebx, [right]\n"
        "      xor ecx, ecx\n"
        "      mov cl, [ebx+eax]\n"
        "      \n"
        "      cmp edx, ecx\n"
        "      jnz .false\n"
        "\n"
        "      inc eax\n"
        "      jmp .while\n"
        "    .endwhile:\n"
        "\n"
        "    mov eax, 1\n"
        "    return\n"
        "\n"
        "  .false:\n"
        "    mov eax, 0 \n"
        "    return\n"
        "\n"
        "    %undef left\n"
        "    %undef right\n"
        "    %undef left_len\n"
        "    %undef l\n"
        "    %undef r\n"
        "\n"
        "malloc:    \n"
        "    %define size   ebp+8\n"
        "\n"
        "    begin 0\n"
        "\n"
        "    cmp [size], dword 0\n"
        "    jnz .alloc\n"
        "\n"
        "    mov eax, 0\n"
        "    return\n"
        "\n"
        "    .alloc:\n"
        "      mov eax, mem        \n"
        "      add eax, [mem_ptr]  \n"
        "      add eax, [size]       \n"
        "  \n"
        "      mov ebx,  mem      \n"
        "      add ebx, MEMORY_SIZE \n"
        "\n"
        "      cmp eax, ebx\n"
        "      jg .no_memory_left\n"
        "\n"
        "      \n"
        "      mov eax, mem\n"
        "      add eax, [mem_ptr]\n"
        "  \n"
        "      \n"
        "      mov ebx, [mem_ptr]\n"
        "      add ebx, [size]\n"
        "      mov [mem_ptr], ebx\n"
        "\n"
        "      return\n"
        "    \n"
        "   .no_memory_left:\n"
        "      addarg str_no_mem_left\n"
        "      call imprima_literal\n"
        "      clargs 1\n"
        "      exit 1\n"
        "\n"
        "    %undef size\n"
        "\n"
        "leia_caractere:\n"
        "    %define buffer   ebp-BUFFER_SIZE\n"
        "    begin BUFFER_SIZE\n"
        "    \n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg BUFFER_SIZE\n"
        "    call readline\n"
        "    clargs 2\n"
        "    \n"
        "    lea ebx, [buffer]\n"
        "    xor eax, eax\n"
        "    mov al, [ebx]\n"
        "\n"
        "    return\n"
        "\n"
        "    %undef buffer\n"
        "\n"
        "leia_real:\n"
        "    %define buffer   ebp-BUFFER_SIZE    \n"
        "    begin BUFFER_SIZE\n"
        "    \n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg BUFFER_SIZE\n"
        "    call readline\n"
        "    clargs 2\n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    call atof\n"
        "    clargs 1\n"
        "\n"
        "    return\n"
        "\n"
        "    %undef buffer\n"
        "\n"
        "leia_inteiro:\n"
        "    %define buffer   ebp-BUFFER_SIZE\n"
        "    begin BUFFER_SIZE\n"
        "    \n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg BUFFER_SIZE\n"
        "    call readline\n"
        "    clargs 2\n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    call atoi\n"
        "    clargs 1\n"
        "\n"
        "    return\n"
        "    %undef buffer\n"
        "\n"
        "leia_logico:\n"
        "    %define zero_str ebp-4\n"
        "    %define buffer   ebp-4-BUFFER_SIZE\n"
        "    begin (4+BUFFER_SIZE)\n"
        "    \n"
        "    mov [zero_str], dword 0x00000030 \n"
        "\n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg BUFFER_SIZE\n"
        "    call readline\n"
        "    clargs 2\n"
        "\n"
        "    \n"
        "    lea eax, [buffer]\n"
        "    addarg eax\n"
        "    addarg str_false\n"
        "    call strcmp\n"
        "    clargs 2\n"
        "\n"
        "    cmp eax, 1\n"
        "    jz .false\n"
        "\n"
        "    \n"
        "    lea eax, [zero_str]\n"
        "    lea ebx, [buffer]\n"
        "    addarg eax\n"
        "    addarg ebx\n"
        "    call strcmp\n"
        "    clargs 2\n"
        "\n"
        "    cmp eax, 1\n"
        "    jz .false\n"
        "\n"
        "    mov eax, 1\n"
        "    return\n"
        "\n"
        "    .false:\n"
        "      mov eax, 0\n"
        "      return\n"
        "\n"
        "    %undef zero_str\n"
        "    %undef buffer\n"
        "\n"
        "leia_literal:\n"
        "    %define string ebp-4\n"
        "    begin 4\n"
        "\n"
        "    addarg BUFFER_SIZE\n"
        "    call malloc\n"
        "    clargs 1\n"
        "\n"
        "    mov [string], eax\n"
        "\n"
        "    addarg dword [string]\n"
        "    addarg BUFFER_SIZE\n"
        "    call readline\n"
        "    clargs 2\n"
        "\n"
        "    mov eax, [string]\n"
        "    return\n"
        "\n"
        "    %undef string\n"
        "\n"
        "clone_literal:\n"
        "  %define string ebp+8\n"
        "  %define lit ebp-4\n"
        "  begin 4\n"
        "\n"
        "  addarg dword [string]\n"
        "  call strlen\n"
        "  clargs 1\n"
        "\n"
        "  inc eax\n"
        "  \n"
        "  addarg eax\n"
        "  call malloc\n"
        "  clargs 1\n"
        "\n"
        "  mov [lit], eax\n"
        "\n"
        "  addarg dword [string]\n"
        "  addarg dword [lit]\n"
        "  call strcpy\n"
        "  clargs 2\n"
        "  \n"
        "  mov eax, [lit]\n"
        "  return\n"
        "\n"
        "  %undef string\n"
        "  %undef lit\n"
        "\n";
