Advertisement
Guest User

Untitled

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