Advertisement
mikhubble

Untitled

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