Judge:Help/aplusb.asm

From PEGWiki
Jump to: navigation, search
%macro  getchar 1                       ;"getchar()"
        cmp     byte [esi],0
        jnz     .getchar_bottom
        push    eax
        push    ebx
        push    ecx
        push    edx
        mov     eax,3                   ;sys_read
        mov     ebx,0                   ;stdin
        mov     ecx,esi                 ;buf
        mov     edx,100                 ;#bytes
        int     0x80
        add     esi,eax                 ;just after last byte
        mov     byte [esi],0            ;so we remember
        sub     esi,eax
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
.getchar_bottom:
        mov     %1,byte [esi]
        inc     esi
%endmacro
%macro  putchar 1
        mov     byte [edi],%1
        inc     edi
%endmacro
section .text
        global _start                   ;must be declared for linker (ld)
_start:
        mov     esi,indata
        mov     byte [esi],0
        mov     edi,outdata             ;output pointer
        call    getint
        mov     ebx,eax
        call    getint
        add     eax,ebx
        call    putint
        putchar 10                      ;"printf("\n")"
        mov     eax,4                   ;sys_write
        mov     ebx,1                   ;stdout
        mov     ecx,outdata
        mov     edx,edi
        sub     edx,outdata             ;#bytes
        int     0x80                    ;"write(stdout,outdata,edi-outdata)"
        mov     eax,1                   ;sys_exit
        mov     ebx,0                   ;success
        int     0x80                    ;"exit(0)"
 
getint:                                 ;"scanf("%d",&eax)"
        mov     eax,0
        push    ebx
        mov     ebx,0
        mov     ecx,0                   ;negative or not
getint_eatwhite:
        getchar bl
        cmp     ebx,32
        jg      getint_top
        jmp     getint_eatwhite
getint_top:
        cmp     ebx,'-'
        jnz     getint_notminus
        getchar bl
        mov     ecx,1
getint_notminus:
        sub     ebx,'0'
        lea     eax,[4*eax+eax]         ;eax *= 5
        shl     eax,1                   ;eax *= 2
        add     eax,ebx
        getchar bl
        cmp     ebx,32
        jle     getint_bottom
        jmp     getint_top
getint_bottom:
        cmp     ecx,0
        jz      getint_return
        neg     eax
getint_return:
        pop     ebx
        ret
 
putint:                                 ;"printf("%d",eax)"
        cmp     eax,0
        jge     putint_nonnegative
        neg     eax
        putchar 45                      ;minus sign
putint_nonnegative:
        cmp     eax,10
        jl      putint_base
        mov     edx,0
        mov     ebx,10
        div     ebx
        push    edx
        call    putint
        pop     edx
        add     edx,'0'
        putchar dl
        ret
putint_base:
        add     eax,'0'
        putchar al
        ret
read:
 
 
section .bss
indata  resb    20
outdata resb    20