Ladies_Man

#ccc added RTLWriteInteger

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