Advertisement
Ladies_Man

#ccc added RTLEOF/EOLN/ReadLn

Jan 6th, 2017
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #==========================================
  2. #------------------data--------------------
  3. #==========================================
  4. .section .data
  5.  
  6. RTLWriteIntegerBuffer:
  7.     .byte 0x3c,0x3d,0x3e,0x00       #    <=>\0
  8.     .byte 0x3c,0x3d,0x3e,0x00       #    <=>\0
  9.     .byte 0x3c,0x3d,0x3e,0x00       #    <=>\0
  10.          
  11. ReadCharBuffer:
  12.     .byte 0x3d
  13.                  
  14. ReadCharInited:
  15.     .byte 0
  16.            
  17. IsEOF:
  18.     .byte 0x30
  19.    
  20. #==========================================
  21. #-------------------bss--------------------
  22. #==========================================    
  23. .section .bss
  24.    
  25.     .macro pushall
  26.         pushq %rdi
  27.         pushq %rsi
  28.         pushq %rbp
  29.         pushq %rsp
  30.         pushq %rdx
  31.         pushq %rcx
  32.         pushq %rbx
  33.         pushq %rax
  34.        
  35.     .endm
  36.    
  37.     .macro popall
  38.         popq %rax
  39.         popq %rbx
  40.         popq %rcx
  41.         popq %rdx
  42.         popq %rsp
  43.         popq %rbp
  44.         popq %rsi
  45.         popq %rdi
  46.     .endm
  47.    
  48.     .macro parleft
  49.         pushq $'{'
  50.         call RTLWriteChar
  51.         addq $8,    %rsp
  52.     .endm
  53.    
  54.     .macro parright
  55.         pushq $'}'
  56.         call RTLWriteChar
  57.         addq $8,    %rsp
  58.     .endm
  59.    
  60.     .macro space
  61.         pushq $' '
  62.         call RTLWriteChar
  63.         addq $8,    %rsp
  64.     .endm
  65.        
  66.     .macro raxchar
  67.         pushq %rax
  68.         call RTLWriteChar
  69.         addq $8,    %rsp
  70.     .endm
  71.    
  72.     .macro raxint
  73.         pushq %rax
  74.         pushq $1
  75.         call RTLWriteInteger
  76.         addq $16,    %rsp
  77.     .endm
  78.    
  79. #==========================================
  80. #------------------text--------------------
  81. #==========================================
  82. .section .text
  83.  
  84. .globl _start
  85. _start:
  86.     jmp StubEntryPoint
  87.  
  88. /*
  89. 1.    RTLHalt — остановка программы,
  90. 2. X  RTLWriteChar — запись char’а на stdout,
  91. 3. X  RTLWriteInteger — запись целого на stdout, принимает два параметра: число и ширину вывода,
  92. 4. X  RTLWriteLn — выводит на stdout символ новой строки (13, 10),
  93. 5. X  RTLReadChar — считывает символ из stdin, результат кладёт в EAX,
  94. 6. X  RTLReadInteger — считывает целое из stdin, результат кладёт в EAX,
  95. 7.    RTLReadLn — пропускает стандартный ввод до конца файла или ближайшего перевода строки,
  96. 8. X  RTLEOF — возвращает в EAX число 1, если достигнут конец файла (следующий символ прочитать невозможно) или 0 в противном случае,
  97. 9. X  RTLEOLN — возвращает в EAX число 1, если следующий символ \n, 0 — в противном случае.
  98.  
  99. 10.   MMAP
  100. 11.   MUNMAP
  101. **/
  102. #------------------------------------------
  103. #----------------WriteChar-----------------
  104. #------------------------------------------
  105. RTLWriteChar:
  106.     pushall
  107.     movq %rsp,   %rbp    #better use base ptr to stack frame
  108.                         #instead of stack itself
  109.     movq $1,    %rax    #syscall №
  110.     movq $1,    %rdi    #param1, fd
  111.     movq %rbp,  %rsi    #p2, buf
  112.     addq $72,   %rsi    #stack:[0-ret,8-arg1,16-arg2]
  113.     movq $1,    %rdx    #p3, count
  114.  
  115.     syscall
  116.    
  117.     popall
  118.     ret
  119.    
  120. #------------------------------------------
  121. #--------------WriteInteger----------------
  122. #------------------------------------------    
  123. RTLWriteInteger:
  124.     pushq %rbp
  125.     movq %rsp,  %rbp
  126.    
  127.     movq 16(%rbp),  %rbx    #arg: count (stdout width)
  128.     movq 24(%rbp),  %rax    #arg: num
  129.    
  130.     cmpq $0,    %rax
  131.     jnl RTLWriteIntegerNotSigned
  132.        
  133.         negq %rax
  134.         decq %rbx
  135.         pushq $'-'              #dont forget to pop
  136.         call RTLWriteChar
  137.         addq $8, %rsp           #pop
  138.    
  139.     RTLWriteIntegerNotSigned:
  140.     xorq %rcx,  %rcx
  141.     pushq %rax
  142.     pushq %rbx
  143.    
  144.     RTLWriteIntegerPreCheckLoop:
  145.         testq %rax, %rax
  146.         jz RTLWriteIntegerPreCheckLoopDone
  147.         incq %rcx
  148.         movq $10,   %rbx
  149.         xorq %rdx,  %rdx
  150.         idiv %rbx          
  151.        
  152.         jmp RTLWriteIntegerPreCheckLoop
  153.        
  154.     RTLWriteIntegerPreCheckLoopDone:
  155.     testq %rcx, %rcx
  156.     setz %dl                        #dl: 0 == rcx ? 1 : 0
  157.     orb %dl,    %cl
  158.    
  159.     popq %rbx
  160.     popq %rax
  161.     subq %rcx,  %rbx
  162.    
  163.     cmpq $0,    %rbx
  164.     jle RTLWriteIntegerNotPadding
  165.         pushq %rcx
  166.    
  167.         RTLWriteIntegerPaddingLoop:
  168.             pushq $' '              #pop!
  169.             call RTLWriteChar
  170.             addq $8,    %rsp        #pop
  171.             decq %rbx
  172.         jnz RTLWriteIntegerPaddingLoop
  173.         popq %rcx
  174.    
  175.     RTLWriteIntegerNotPadding:
  176.     #find last digit's address:    
  177.    #we write from right to left cuz each time we divide number by 10, we only know it's right-most digit
  178.     #so we need to write right-most digit into right-most byte:
  179.    
  180.     #e.g: num=-123; count=4
  181.     #init buffer:   |0x3b|0x3d|0x3e|0x00|0x3b|...
  182.     #1st iter:      |0x3b|0x3d| 3d |0x00|0x3b|...
  183.     #2st iter:      |0x3b| 2d | 3d |0x00|0x3b|...
  184.     #3st iter:      | 1d | 2d | 3d |0x00|0x3b|...
  185.    
  186.     movq $RTLWriteIntegerBuffer, %rdi   #leaq RTLWriteIntegerBuffer-1(%rcx), %rdi
  187.     addq %rcx,  %rdi                    #-||-
  188.     decq %rdi                           #-||-
  189.     #LEA EDI,[OFFSET RTLWriteIntegerBuffer+ECX-1]
  190.    
  191.     pushq %rcx              #we dont care if (count < real_num_width)
  192.  
  193.     RTLWriteIntegerLoop:
  194.         movq $10,   %rsi
  195.         xorq %rdx,  %rdx
  196.         idiv %rsi
  197.         #convert to string
  198.         movq %rdx,  %rbx    #leaq '0'(%rdx), %rbx equivalent
  199.         addq $'0',  %rbx    #-||-
  200.        
  201.         movb %bl, (%rdi)
  202.         decq %rdi
  203.     loop RTLWriteIntegerLoop
  204.    
  205.     popq %rcx
  206.    
  207.     #invoke WriteFile
  208.     movq $1,    %rax                    #syscall
  209.     movq $1,    %rdi                    #param1, fd
  210.     movq $RTLWriteIntegerBuffer,  %rsi  #p2, buf
  211.     movq %rcx,    %rdx                  #p3, count
  212.  
  213.     syscall
  214.    
  215.     popq %rbp
  216.     ret
  217.    
  218. #------------------------------------------
  219. #-----------------WriteLn------------------
  220. #------------------------------------------    
  221. RTLWriteLn:
  222.     pushq $13
  223.     call RTLWriteChar
  224.     addq $8,    %rsp
  225.    
  226.     pushq $10
  227.     call RTLWriteChar
  228.     addq $8,    %rsp
  229.  
  230.     ret
  231.    
  232.      
  233. ReadCharEx:
  234.     pushall
  235.     movq %rsp,  %rbp
  236.    
  237.     movq %rax, %rbx         #copy rax to rbx cuz of rax's usage in syscall
  238.    
  239.    movq $0,    %rax            #syscall read
  240.    movq $0,    %rdi            #p1:stdin
  241.    movq $ReadCharBuffer,  %rsi #p2:buffer
  242.    movq $1,    %rdx            #p3:count
  243.    syscall
  244.  
  245.    testq %rbx, %rbx    
  246.    setz %bl                    #al: 0 == rax ? 1 : 0
  247.    orb %bl,    IsEOF
  248.  
  249.    popall
  250.    ret
  251.    
  252. ReadCharInit:
  253.    cmpb $0,    (ReadCharInited)
  254.    jnz ReadInitDone
  255.    
  256.        call ReadCharEx
  257.        movb $1,    (ReadCharInited)
  258.  
  259.    ReadInitDone:
  260.    ret
  261.  
  262. #------------------------------------------
  263. #----------------ReadChar------------------
  264. #------------------------------------------    
  265. RTLReadChar:
  266.    call ReadCharInit
  267.  
  268.    xorq %rax, %rax
  269.    movb ReadCharBuffer,   %al    #movzx (ReadCharBuffer), %rax
  270.    movzx %al, %rax
  271.    
  272.    call ReadCharEx
  273.  
  274.    ret
  275.  
  276. #------------------------------------------
  277. #--------------ReadInteger-----------------
  278. #------------------------------------------    
  279. RTLReadInteger:
  280.    call ReadCharInit
  281.    
  282.    pushall
  283.    movq %rsp,  %rbp
  284.    
  285.    movq $1, %rcx    #leaq 1(%rax,%rbx=0,1), %rcx  equivalent
  286.    
  287.    ReadIntegerSkipWhiteSpace:
  288.        cmpb $'1',    IsEOF
  289.        jnz ReadIntegerDone
  290.        cmpb $0,    ReadCharBuffer
  291.        je ReadIntegerSkipWhiteSpaceDone
  292.        cmpb $32,   ReadCharBuffer          #$32=space
  293.        ja ReadIntegerSkipWhiteSpaceDone
  294.        
  295.        call ReadCharEx
  296.        
  297.        jmp ReadIntegerSkipWhiteSpace
  298.        
  299.    ReadIntegerSkipWhiteSpaceDone:
  300.    cmpb $'-',  (ReadCharBuffer)
  301.    jne ReadIntegerNotSigned
  302.        
  303.        negq %rcx
  304.        call ReadCharEx
  305.        
  306.    ReadIntegerNotSigned:
  307.    ReadIntegerLoop:
  308.        xorq %rbx, %rbx
  309.        movb ReadCharBuffer,  %bl
  310.        
  311.        cmpb $'0',  %bl
  312.        jb ReadIntegerDone
  313.        cmpb $'9',  %bl
  314.        ja ReadIntegerDone
  315.        
  316.        imul $10,   %rax            #rax *= 10
  317.        #cast string to int:
  318.        subq $'0',  %rbx            #lea -'0'(%rax,%rbx,1),  %rax
  319.        addq %rbx,  %rax            #-||-
  320.        
  321.        call ReadCharEx
  322.        jmp ReadIntegerLoop
  323.    
  324.    ReadIntegerDone:
  325.    imul %rcx               #rax *= rcx  (rcx={1;-1})
  326.    
  327.    pushq %rax
  328.    pushq $0
  329.    call RTLWriteInteger   #print out rax
  330.    addq $16,    %rsp
  331.    
  332.    popall
  333.    ret
  334.  
  335. #------------------------------------------
  336. #------------------ReadLn------------------
  337. #------------------------------------------        
  338. RTLReadLn:
  339.    call ReadCharInit
  340.    
  341.    parleft
  342.    pushq (ReadCharBuffer)
  343.    call RTLWriteChar
  344.    addq $8,    %rsp
  345.    
  346.    pushq (IsEOF)
  347.    call RTLWriteChar
  348.    addq $8,    %rsp
  349.    
  350.    pushq IsEOF
  351.    call RTLWriteChar
  352.    addq $8,    %rsp
  353.    parright
  354.    
  355.    
  356.    cmpb $'1',    IsEOF                  
  357.    jne ReadLnDone
  358.    
  359.        movb ReadCharBuffer,    %bl    
  360.        cmpb $10,   %bl                 #cmp to LF
  361.        je ReadLnDone
  362.    
  363.    call ReadCharEx
  364.    jmp RTLReadLn
  365.    
  366.    ReadLnDone:
  367.    ret
  368.  
  369. #------------------------------------------
  370. #-------------------EOF--------------------
  371. #------------------------------------------        
  372. RTLEOF:
  373.    xorq %rax,  %rax
  374.  
  375.    cmpb $'1', IsEOF
  376.    jne noteof
  377.        movq $1,    %rax
  378.        ret
  379.    
  380.    noteof:
  381.    movq $0,    %rax
  382.    ret
  383.  
  384. #------------------------------------------
  385. #------------------EOLN--------------------
  386. #------------------------------------------    
  387. RTLEOLN:
  388.    cmpb $10,   ReadCharBuffer
  389.    sete %bl
  390.    ret
  391.  
  392. #------------------------------------------
  393. #------------------Halt--------------------
  394. #------------------------------------------        
  395. RTLHalt:
  396.    movq $60,   %rax
  397.    movq $0,    %rdi
  398.    syscall
  399.  
  400.  
  401. #//==----------------------------------==//
  402. #//----------------ENTRY-----------------//
  403. #//==----------------------------------==//
  404. StubEntryPoint:
  405.    #syscall mmap here
  406.  
  407.    /*pushq $-123
  408.    pushq $5
  409.    call RTLWriteInteger  
  410.    call RTLWriteLn
  411.  
  412.    pushq $'A'
  413.    call RTLWriteChar   #write 'A'
  414.    addq $8,    %rsp
  415.    call RTLWriteLn*/
  416.  
  417.    #call RTLReadChar    #read from stdin to rax
  418.    #call RTLReadInteger
  419.    #space
  420.    #call RTLReadInteger
  421.    call RTLReadLn
  422.    call RTLReadInteger
  423.  
  424.    call RTLEOF
  425.    parleft
  426.    raxchar
  427.    raxint
  428.    parright
  429.  
  430.    call RTLHalt
  431.    /*
  432.    gdb:
  433.    info files
  434.    b *0x4000xx
  435.    run
  436.    si 1
  437.    ni 1
  438.    x/5i $pc
  439.    x/8g $sp
  440.    info registers
  441.    p $rax
  442.    set $rax = 0x123
  443.    */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement