Advertisement
Guest User

Untitled

a guest
Apr 18th, 2015
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.                 section         .text
  2.  
  3.                 global          _start
  4. _start:
  5.  
  6.                 sub             rsp, 2 * 128 * 8
  7.                 lea             rdi, [rsp + 128 * 8]
  8.                 mov             rcx, 128
  9.                 call            read_long
  10.                 mov             rdi, rsp
  11.                 call            read_long
  12.                 lea             rsi, [rsp + 128 * 8]
  13.                 call            mul_long_long
  14.  
  15.                 call            write_long
  16.  
  17.                 mov             al, 0x0a
  18.                 call            write_char
  19.  
  20.                 jmp             exit
  21.  
  22. ; adds two long number
  23. ;    rdi -- address of summand #1 (long number)
  24. ;    rsi -- address of summand #2 (long number)
  25. ;    rcx -- length of long numbers in qwords
  26. ; result:
  27. ;    sum is written to rdi
  28. add_long_long:
  29.                 push            rdi
  30.                 push            rsi
  31.                 push            rax
  32.                 push            rbx
  33.                 push            rcx
  34.                 push            rdx
  35.  
  36.  
  37.                 clc
  38. .loop:
  39.                 mov             rax, [rsi]
  40.                 lea             rsi, [rsi + 8]
  41.                 adc             [rdi], rax
  42.                 lea             rdi, [rdi + 8]
  43.                 dec             rcx
  44.                 jnz             .loop
  45.  
  46.                 push            rdx
  47.                 push            rcx
  48.                 push            rbx
  49.                 push            rax
  50.                 pop             rsi
  51.                 pop             rdi
  52.                 ret
  53.  
  54. ; subtract two long number
  55. ;    rdi -- address of summand #1 (long number)
  56. ;    rsi -- address of summand #2 (long number)
  57. ;    rcx -- length of long numbers in qwords
  58. ; result:
  59. ;    sub is written to rdi
  60. sub_long_long:
  61.                 push            rsi
  62.                 push            rdi
  63.                 push            rcx
  64.  
  65.                 clc
  66. .loop:
  67.                 mov             rax, [rdi]
  68.                 lea             rdi, [rdi + 8]
  69.                 sbb             [rsi], rax
  70.                 lea             rsi, [rsi + 8]
  71.                 dec             rcx
  72.                 jnz             .loop
  73.  
  74.                 pop             rcx
  75.                 pop             rsi
  76.                 pop             rdi
  77.                 ret
  78.  
  79.  
  80. mul_long_long:
  81.                 push rdi
  82.                 push rsi
  83.                 push rcx
  84.  
  85.                 clc
  86.  
  87.                 lea             rsi, [rsi + 128 * 8]
  88.  
  89. .rsiloop:
  90.                 pop             rdx
  91.                 push            rdx
  92.                 sub             rdx, rcx
  93.  
  94.                 push            rdi
  95.                 push            rsi
  96.                 push            rax
  97.                 push            rbx  ;carry
  98.                 push            rcx
  99.  
  100. .rdiloop:
  101.  
  102.                 xor             rbx, rbx
  103.  
  104.                 mov             rax, [rdi]
  105.                 push            rbx
  106.                 mov             rbx, [rsi]
  107.                 mul             rbx
  108.                 pop             rbx
  109.  
  110.                 add             rax, rbx
  111.                 adc             rdx, 0
  112.                 mov             [rsi], rax
  113.                 add             rdi, 8
  114.                 mov             rbx, rdx
  115.                 dec             rdx
  116. jnz             .rdiloop
  117.  
  118.                 lea             rsi, [rsi - 8]
  119.                 dec             rcx
  120. jnz             .rsiloop
  121.  
  122.                 pop rcx
  123.                 pop rsi
  124.                 pop rdi
  125.                 ret
  126.  
  127. ; adds 64-bit number to long number
  128. ;    rdi -- address of summand #1 (long number)
  129. ;    rax -- summand #2 (64-bit unsigned)
  130. ;    rcx -- length of long number in qwords
  131. ; result:
  132. ;    sum is written to rdi
  133. add_long_short:
  134.                 push            rdi
  135.                 push            rcx
  136.                 push            rdx
  137.  
  138.                 xor             rdx,rdx
  139. .loop:
  140.                 add             [rdi], rax
  141.                 adc             rdx, 0
  142.                 mov             rax, rdx
  143.                 xor             rdx, rdx
  144.                 add             rdi, 8
  145.                 dec             rcx
  146.                 jnz             .loop
  147.  
  148.                 pop             rdx
  149.                 pop             rcx
  150.                 pop             rdi
  151.                 ret
  152.  
  153. ; multiplies long number by a short
  154. ;    rdi -- address of multiplier #1 (long number)
  155. ;    rbx -- multiplier #2 (64-bit unsigned)
  156. ;    rcx -- length of long number in qwords
  157. ; result:
  158. ;    product is written to rdi
  159. mul_long_short:
  160.                 push            rax
  161.                 push            rbx
  162.                 push            rcx
  163.                 push            rdx
  164.                 push            rdi
  165.  
  166.                 xor             rsi, rsi
  167. .loop:
  168.                 mov             rax, [rdi]
  169.                 mul             rbx
  170.                 add             rax, rsi
  171.                 adc             rdx, 0
  172.                 mov             [rdi], rax
  173.                 add             rdi, 8
  174.                 mov             rsi, rdx
  175.                 dec             rcx
  176.                 jnz             .loop
  177.  
  178.                 pop             rdi
  179.                 pop             rdx
  180.                 pop             rcx
  181.                 pop             rbx
  182.                 pop             rax
  183.                 ret
  184.  
  185. ; divides long number by a short
  186. ;    rdi -- address of dividend (long number)
  187. ;    rbx -- divisor (64-bit unsigned)
  188. ;    rcx -- length of long number in qwords
  189. ; result:
  190. ;    quotient is written to rdi
  191. ;    rdx -- remainder
  192. div_long_short:
  193.                 push            rdi
  194.                 push            rax
  195.                 push            rcx
  196.  
  197.                 lea             rdi, [rdi + 8 * rcx - 8]
  198.                 xor             rdx, rdx
  199.  
  200. .loop:
  201.                 mov             rax, [rdi]
  202.                 div             rbx
  203.                 mov             [rdi], rax
  204.                 sub             rdi, 8
  205.                 dec             rcx
  206.                 jnz             .loop
  207.  
  208.                 pop             rcx
  209.                 pop             rax
  210.                 pop             rdi
  211.                 ret
  212.  
  213. ; assigns a zero to long number
  214. ;    rdi -- argument (long number)
  215. ;    rcx -- length of long number in qwords
  216. set_zero:
  217.                 push            rax
  218.                 push            rdi
  219.                 push            rcx
  220.  
  221.                 xor             rax, rax
  222.                 rep stosq
  223.  
  224.                 pop             rcx
  225.                 pop             rdi
  226.                 pop             rax
  227.                 ret
  228.  
  229. ; checks if a long number is a zero
  230. ;    rdi -- argument (long number)
  231. ;    rcx -- length of long number in qwords
  232. ; result:
  233. ;    ZF=1 if zero
  234. is_zero:
  235.                 push            rax
  236.                 push            rdi
  237.                 push            rcx
  238.  
  239.                 xor             rax, rax
  240.                 rep scasq
  241.  
  242.                 pop             rcx
  243.                 pop             rdi
  244.                 pop             rax
  245.                 ret
  246.  
  247. ; read long number from stdin
  248. ;    rdi -- location for output (long number)
  249. ;    rcx -- length of long number in qwords
  250. read_long:
  251.                 push            rcx
  252.                 push            rdi
  253.  
  254.                 call            set_zero
  255. .loop:
  256.                 call            read_char
  257.                 or              rax, rax
  258.                 js              exit
  259.                 cmp             rax, 0x0a
  260.                 je              .done
  261.                 cmp             rax, '0'
  262.                 jb              .invalid_char
  263.                 cmp             rax, '9'
  264.                 ja              .invalid_char
  265.  
  266.                 sub             rax, '0'
  267.                 mov             rbx, 10
  268.                 call            mul_long_short
  269.                 call            add_long_short
  270.                 jmp             .loop
  271.  
  272. .done:
  273.                 pop             rdi
  274.                 pop             rcx
  275.                 ret
  276.  
  277. .invalid_char:
  278.                 mov             rsi, invalid_char_msg
  279.                 mov             rdx, invalid_char_msg_size
  280.                 call            print_string
  281.                 call            write_char
  282.                 mov             al, 0x0a
  283.                 call            write_char
  284.  
  285. .skip_loop:
  286.                 call            read_char
  287.                 or              rax, rax
  288.                 js              exit
  289.                 cmp             rax, 0x0a
  290.                 je              exit
  291.                 jmp             .skip_loop
  292.  
  293. ; write long number to stdout
  294. ;    rdi -- argument (long number)
  295. ;    rcx -- length of long number in qwords
  296. write_long:
  297.                 push            rax
  298.                 push            rcx
  299.  
  300.                 mov             rax, 20
  301.                 mul             rcx
  302.                 mov             rbp, rsp
  303.                 sub             rsp, rax
  304.  
  305.                 mov             rsi, rbp
  306.  
  307. .loop:
  308.                 mov             rbx, 10
  309.                 call            div_long_short
  310.                 add             rdx, '0'
  311.                 dec             rsi
  312.                 mov             [rsi], dl
  313.                 call            is_zero
  314.                 jnz             .loop
  315.  
  316.                 mov             rdx, rbp
  317.                 sub             rdx, rsi
  318.                 call            print_string
  319.  
  320.                 mov             rsp, rbp
  321.                 pop             rcx
  322.                 pop             rax
  323.                 ret
  324.  
  325. ; read one char from stdin
  326. ; result:
  327. ;    rax == -1 if error occurs
  328. ;    rax \in [0; 255] if OK
  329. read_char:
  330.                 push            rcx
  331.                 push            rdi
  332.  
  333.                 sub             rsp, 1
  334.                 xor             rax, rax
  335.                 xor             rdi, rdi
  336.                 mov             rsi, rsp
  337.                 mov             rdx, 1
  338.                 syscall
  339.  
  340.                 cmp             rax, 1
  341.                 jne             .error
  342.                 xor             rax, rax
  343.                 mov             al, [rsp]
  344.                 add             rsp, 1
  345.  
  346.                 pop             rdi
  347.                 pop             rcx
  348.                 ret
  349. .error:
  350.                 mov             rax, -1
  351.                 add             rsp, 1
  352.                 pop             rdi
  353.                 pop             rcx
  354.                 ret
  355.  
  356. ; write one char to stdout, errors are ignored
  357. ;    al -- char
  358. write_char:
  359.                 sub             rsp, 1
  360.                 mov             [rsp], al
  361.  
  362.                 mov             rax, 1
  363.                 mov             rdi, 1
  364.                 mov             rsi, rsp
  365.                 mov             rdx, 1
  366.                 syscall
  367.                 add             rsp, 1
  368.                 ret
  369.  
  370. exit:
  371.                 mov             rax, 60
  372.                 xor             rdi, rdi
  373.                 syscall
  374.  
  375. ; print string to stdout
  376. ;    rsi -- string
  377. ;    rdx -- size
  378. print_string:
  379.                 push            rax
  380.  
  381.                 mov             rax, 1
  382.                 mov             rdi, 1
  383.                 syscall
  384.  
  385.                 pop             rax
  386.                 ret
  387.  
  388.  
  389.                 section         .rodata
  390. invalid_char_msg:
  391.                 db              "Invalid character: "
  392. invalid_char_msg_size: equ             $ - invalid_char_msg
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement