Advertisement
Guest User

Untitled

a guest
Jun 17th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; The OS/K Team licenses this file to you under the MIT license.
  2. ; See the LICENSE file in the project root for more information.
  3.  
  4. _doprnt_test:
  5.     mov ax0, .fmt
  6.     sub rsp, 128
  7.     mov q[rsp+40], 0x7FE
  8.     mov q[rsp+32], -2
  9.     mov q[rsp+24], 666
  10.     mov q[rsp+16], 0x112233DDAA6677BB
  11.     mov q[rsp+8], 'K'
  12.     mov q[rsp], .str
  13.     call printf
  14.     add rsp, 128
  15.  
  16.     ret
  17.  
  18. .fmt = "%% Hello World %s - %c - %p - %d - %d - %b"
  19. .str = "(cc)"
  20.  
  21. ;
  22. ; typedef int (*PUTC)(int ch)
  23. ; int _doprnt(PUTC putc, int n, const char *fmt, va_list ap)
  24. ;
  25. _doprnt:
  26.     enter 8
  27.     mov q[rbp-8], rbx
  28.     mov q[rbp-16], nx0
  29.     mov q[rbp-24], nx1
  30.     mov q[rbp-32], nx2
  31.     mov q[rbp-40], rdi
  32.     mov q[rbp-48], rsi
  33.     mov q[rbp-56], nx3
  34.  
  35.     mov rbx, ax2        ; fmt
  36.     mov nx3, ax0        ; putc
  37.     mov nx0, ax1        ; n
  38.     xor nx1, nx1        ; return value
  39.     xor nx2, nx2        ; index in va_list
  40.     mov rsi, ax3        ; ap
  41.  
  42. .main_loop:
  43.     ; find '%' or null-terminator
  44.     mov rcx, STRLEN_MAX
  45.     mov rdi, rbx
  46.     scasb.rep.nz rdi, '%'
  47.  
  48. .print_regular:
  49.     ; everything below rdi is a regular character; print it
  50.     cmp rbx, rdi
  51.     j.z .check_modf
  52.  
  53.     mov ax0, b[rbx]
  54.     call .doput
  55.  
  56.     inc rbx
  57.     jmp .print_regular
  58.  
  59. .check_modf:
  60.     ; did we find a '%' ?
  61.     cmp b[rbx], '%'
  62.     j.nz .epilogue  ; no, we found fmt's null-terminator; we're done
  63.  
  64.     ; we did find a modifier / '%'
  65.     mov rax, b[rbx+1]
  66.     add rbx, 2
  67.  
  68.     cmp rax, 's'
  69.     j.z .modf_s
  70.     cmp rax, 'c'
  71.     j.z .modf_c
  72.     cmp rax, 'p'
  73.     j.z .modf_p
  74.     cmp rax, 'x'
  75.     j.z .modf_x
  76.     cmp rax, 'u'
  77.     j.z .modf_u
  78.     cmp rax, 'd'
  79.     j.z .modf_d
  80.     cmp rax, 'o'
  81.     j.z .modf_o
  82.     cmp rax, 'b'
  83.     j.z .modf_b
  84.     cmp rax, '%'
  85.     j.z .modf_percent
  86.     ; unrecognized
  87.     jmp .bad_modifier
  88.  
  89. .modf_s:
  90.     ; get string address
  91.     mov rdi, q[rsi + nx2 * 8]
  92.     inc nx2
  93.  
  94.     test rdi, rdi
  95.     j.z .nullstring
  96.  
  97. .print_string:
  98.     mov ax0, b[rdi]
  99.     test ax0, ax0
  100.     j.z .main_loop
  101.  
  102.     inc rdi
  103.     call .doput
  104.     jmp .print_string
  105.  
  106. .modf_c:
  107.     mov ax0, q[rsi + nx2 * 8]
  108.     inc nx2
  109.     call .doput
  110.     jmp .main_loop
  111.  
  112. .modf_p:
  113.     mov ax0, '0'
  114.     call .doput
  115.     mov ax0, 'x'
  116.     call .doput
  117.     ; Fallthrough
  118.  
  119. .modf_x:
  120.     mov ax2, 16
  121.     mov ax3, 1
  122.     jmp .print_number
  123.  
  124. .modf_u:
  125.     mov ax2, 10
  126.     mov ax3, 1
  127.     jmp .print_number
  128.  
  129. .modf_d:
  130.     mov ax2, 10
  131.     xor ax3, ax3
  132.     jmp .print_number
  133.  
  134. .modf_o:
  135.     mov ax2, 8
  136.     mov ax3, 1
  137.     jmp .print_number
  138.  
  139. .modf_b:
  140.     mov ax2, 2
  141.     mov ax3, 1
  142.     jmp .print_number
  143.  
  144. .print_number:
  145.     ; allocate itoa conversion buffer
  146.     sub rsp, 80
  147.     mov rdi, rsp
  148.  
  149.     ; assume modifier already set up ax2 and ax3
  150.     mov ax0, rsp
  151.     mov ax1, q[rsi + nx2 * 8]
  152.     call _itoa
  153.     inc nx2
  154.  
  155. .print_itoa_buf:
  156.     mov ax0, b[rdi]
  157.     test ax0, ax0
  158.     add.z rsp, 80
  159.     j.z .main_loop
  160.  
  161.     inc rdi
  162.     call .doput
  163.     jmp .print_itoa_buf
  164.  
  165. .modf_percent:
  166.     mov ax0, '%'
  167.     call .doput
  168.     jmp .main_loop
  169.  
  170. .bad_modifier:
  171.     ; print "%?" to clearly indicate that something is wrong
  172.     mov ax0, '$'
  173.     call .doput
  174.  
  175.     mov ax0, '?'
  176.     call .doput
  177.  
  178.     jmp .main_loop
  179.  
  180. .nullstring:
  181.     ; %s was passed a NULL
  182.     mov ax0, '('
  183.     call .doput
  184.  
  185.     mov ax0, 'n'
  186.     call .doput
  187.  
  188.     mov ax0, 'u'
  189.     call .doput
  190.  
  191.     mov ax0, 'l'
  192.     call .doput
  193.  
  194.     mov ax0, 'l'
  195.     call .doput
  196.  
  197.     mov ax0, ')'
  198.     call .doput
  199.  
  200.     jmp .main_loop
  201.  
  202. .epilogue:
  203.     mov rax, nx1
  204.     mov rbx, q[rbp-8]
  205.     mov nx0, q[rbp-16]
  206.     mov nx1, q[rbp-24]
  207.     mov nx2, q[rbp-32]
  208.     mov rdi, q[rbp-40]
  209.     mov rsi, q[rbp-48]
  210.     mov nx3, q[rbp-56]
  211.     leave
  212.     ret
  213. ;
  214. ; prints ax0
  215. ;
  216. .doput:
  217.     ; update print count
  218.     inc nx1
  219.  
  220.     ; if n==0, don't print
  221.     ; we follow the C convention that sprintf()-like functions
  222.     ; should return the number of characters that would have
  223.     ; been printed/written if 'n' were big enough
  224.     test nx0, nx0
  225.     ret.z
  226.    
  227.     ; if n>0, decrement n and print
  228.     dec nx0
  229.     call nx3
  230.    
  231.     ; did putc fail?
  232.     cmp rax, 0
  233.     xor.nz nx0, nx0     ; yes, so artificially set n=0
  234.  
  235.     ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement