Advertisement
EWTD

TASM long operations

Jan 7th, 2022
2,400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. include C:/FILES/LAB4M.inc
  2. assume cs: code, ds: data
  3.  
  4. data segment
  5.     strings_max_length equ 102
  6.     dummy              db  0Dh, 0Ah, '$'
  7.     description_string db  "PROGRAM IMPLEMENTING LONG OPERATIONS$"
  8.     input_lhs_string   db  "INPUT LHS:>$"
  9.     input_rhs_string   db  "INPUT RHS:>$"
  10.     multiplication_output_string      db  "LHS*RHS:>$"
  11.     sum_output_string  db  "LHS+RHS:>$"
  12.     sub_output_string  db  "LHS-RHS:>$"
  13.     lhs                db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  14.     rhs                db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  15.     result             db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  16.     buffer1            db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  17.     buffer2            db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  18.     buffer3            db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  19.     buffer4            db  strings_max_length, 0, strings_max_length - 2 dup ('$')
  20.     carry_buffer       db  0
  21.     strerr             db  "error$"
  22.     is_hex_algebra     db  0
  23. data ends
  24.  
  25. code segment
  26. .386
  27. ; newline()
  28. newline proc
  29.                     push dx
  30.                     push ax
  31.                     mov dx, offset dummy
  32.                     mov ax, 0900h
  33.                     int 21h
  34.                     pop ax
  35.                     pop dx
  36.                     ret
  37.                     endp
  38. ; ~ is_zero(char* dst)
  39. ; dst == "0" ? ax = 1: ax = 0
  40. is_zero proc       
  41.                     push bp
  42.                     push si
  43.                     mov bp, sp
  44.                     mov ax, 0
  45.                     mov si, [bp+6]
  46.                     cmp byte ptr [si+1], 1
  47.                     jne is_zero_return
  48.                     cmp byte ptr [si+2], 48
  49.                     jne is_zero_return
  50.                     mov ax, 1
  51.     is_zero_return:
  52.                     pop si
  53.                     pop bp
  54.                     ret 2
  55.                     endp
  56. ; convert_char_to_int(char ch)
  57. ; ch >= A && ch <= 0 ? dx = ch-'A':dx = ch-'0'
  58. convert_char_to_int proc
  59.                     push bp
  60.                     mov bp, sp
  61.                     mov dx, [bp+4]
  62.                     cmp dx, 65
  63.                     jge convert_char_to_int_hex ; dx >= 'A'
  64.     convert_char_to_int_dec:
  65.                     sub dx, 48 ; dx -= '0'
  66.                     jmp convert_char_to_int_return
  67.     convert_char_to_int_hex:
  68.                     sub dx, 65 ; dx -= 'A'
  69.                     add dx, 10
  70.     convert_char_to_int_return:
  71.                     pop bp
  72.                     ret 2
  73.                     endp
  74. ; convert_int_to_char(char value)
  75. ; value >= 10? dx = (value - 10)+'A' : dx = value + '0'
  76. convert_int_to_char proc
  77.                     push bp
  78.                     mov bp, sp
  79.                     mov dx, [bp+4]
  80.                     cmp dx, 10
  81.                     jge convert_int_to_char_hex
  82.     convert_int_to_char_dec:
  83.                     add dx, 48
  84.                     jmp convert_int_to_char_return
  85.     convert_int_to_char_hex:
  86.                     sub dx, 10
  87.                     add dx, 65
  88.     convert_int_to_char_return:
  89.                     pop bp
  90.                     ret 2
  91.                     endp
  92. ; get_value_sign(char* value)
  93. get_value_sign proc
  94.                     push bp
  95.                     mov bp, sp
  96.                     push si
  97.                     mov si, [bp+4]
  98.                     mov dx, 0
  99.                     cmp byte ptr[si+2], 45
  100.                     jne get_value_sign_return
  101.                     inc dx
  102.     get_value_sign_return:
  103.                     pop si
  104.                     pop bp
  105.                     ret 2
  106.                     endp
  107. ;str_push_begin(char* dst, char value)
  108. ;! value == 00**h
  109. str_push_begin proc
  110.                     push bp
  111.                     mov bp, sp
  112.                     push si
  113.                     push di
  114.                     push ax
  115.                     push cx
  116.                     push bx
  117.                     mov si, [bp+6]
  118.                     mov ax, [bp+4]
  119.                     mov cl, byte ptr[si+1]
  120.                     add si, cx
  121.                     inc cx
  122.                     add si, 2
  123.                     mov di, si
  124.                     inc di
  125. ;si = str.end(), di = str.end()+1, cx = len(str)+1
  126.     str_push_begin_shift_loop:
  127.                     mov bl, byte ptr [si]
  128.                     mov byte ptr [di], bl
  129.                     dec di
  130.                     dec si
  131.                     loop str_push_begin_shift_loop
  132.                     mov si, [bp+6]
  133.                     mov byte ptr[si+2],al
  134.                     inc byte ptr[si+1]
  135.                     pop bx
  136.                     pop cx
  137.                     pop ax
  138.                     pop di
  139.                     pop si
  140.                     pop bp
  141.                     ret 4
  142.                     endp
  143. ; str_del_begin(char* dst)
  144. str_del_begin proc
  145.                     push bp
  146.                     mov bp, sp
  147.                     push si
  148.                     push di
  149.                     push cx
  150.                     push ax                    
  151.                     mov si, [bp+4]
  152.                     mov cl, byte ptr[si+1]
  153.                     cmp cl, 0
  154.                     je str_del_begin_return
  155.                     add si, 2
  156.                     mov di, si
  157.                     inc di
  158.     str_del_begin_loop:
  159.                     mov al, byte ptr[di]
  160.                     mov byte ptr[si], al
  161.                     inc si
  162.                     inc di
  163.                     loop str_del_begin_loop
  164.                     mov si, [bp+4]
  165.                     dec byte ptr[si+1]
  166.     str_del_begin_return:
  167.                     pop ax
  168.                     pop cx
  169.                     pop di
  170.                     pop si
  171.                     pop bp
  172.                     ret 2
  173.                     endp
  174. ; str_clear_leading_zeroes(char* dst)
  175. str_clear_leading_zeroes proc
  176.                     push bp
  177.                     mov bp, sp
  178.                     push si
  179.                     mov si, [bp+4]
  180.                     cmp byte ptr[si+2], 48
  181.                     jne str_clear_leading_zeroes_return
  182.     str_clear_leading_zeroes_loop:
  183.                     push si
  184.                     call str_del_begin
  185.                     cmp byte ptr[si+2], 48
  186.                     je str_clear_leading_zeroes_loop
  187.     str_clear_leading_zeroes_return:
  188.                     pop si
  189.                     pop bp
  190.                     ret 2
  191.                     endp
  192. ;strcpy(char* dst, char* src)
  193. strcpy proc
  194.                     push bp
  195.                     mov bp, sp
  196.                     push di
  197.                     push si
  198.                     push cx
  199.                     push ax
  200.                     mov di, [bp+6]
  201.                     mov si, [bp+4]
  202.                     mov cl, byte ptr[si+1]
  203.                     mov byte ptr[di+1], cl
  204.                     add si, 2
  205.                     add di, 2
  206.                     inc cx
  207.     strcpy_loop:
  208.                     mov al, byte ptr[si]
  209.                     mov byte ptr[di], al
  210.                     inc si
  211.                     inc di
  212.                     loop strcpy_loop
  213.                     pop ax
  214.                     pop cx
  215.                     pop si
  216.                     pop di
  217.                     pop bp
  218.                     ret 4
  219.                     endp
  220. ; strclear(char* dst)
  221. strclear proc
  222.                     push bp
  223.                     mov bp, sp
  224.                     push si
  225.                     push cx
  226.                     mov si, [bp+4]
  227.                     mov cl, byte ptr[si+1]
  228.                     mov byte ptr[si+1], 0
  229.                     add si, 2
  230.                     cmp cl, 0
  231.                     je strclear_return
  232.     strclear_loop:
  233.                     mov byte ptr[si], 36
  234.                     inc si
  235.                     loop strclear_loop
  236.     strclear_return:
  237.                     pop cx
  238.                     pop si
  239.                     pop bp
  240.                     ret 2
  241.                     endp
  242. ;strfill_with_zeroes(char* dst, char num)
  243. strfill_with_zeroes proc
  244.                     push bp
  245.                     mov bp, sp
  246.                     push si
  247.                     push cx
  248.                     push ax
  249.                     mov si, [bp+6]
  250.                     mov cx, [bp+4]
  251.                     mov ax, 48
  252.                     cmp cx, 0
  253.                     je strfill_with_zeroes_return
  254.     strfill_with_zeroes_loop:
  255.                     push si
  256.                     push ax
  257.                     call str_push_begin
  258.                     loop strfill_with_zeroes_loop
  259.     strfill_with_zeroes_return:
  260.                     pop ax
  261.                     pop cx
  262.                     pop si
  263.                     pop bp
  264.                     ret 4
  265.                     endp
  266. ; write_result_of_operation(char* dst, char value, char* carry_buffer)
  267. ; ! value == 00**h !
  268. write_result_of_operation proc
  269.                     push bp
  270.                     mov bp, sp
  271.                     push si
  272.                     push di
  273.                     push ax
  274.                     push bx
  275.                     mov si, [bp+8]
  276.                     mov ax, [bp+6]
  277.                     mov di, [bp+4]
  278.                     cmp is_hex_algebra, 1
  279.                     je write_result_of_operation_hex
  280.     write_result_of_operation_dec:
  281.                     mov bl, 10
  282.                     jmp write_result_of_operation_write
  283.     write_result_of_operation_hex:
  284.                     mov bl, 16
  285.     write_result_of_operation_write:
  286.                     div bl ; al /= bl, ah = al % bl
  287.                     mov byte ptr [di], al
  288.                     mov al, ah
  289.                     mov ah, 0
  290.                     push ax
  291.                     call convert_int_to_char
  292.                     push si
  293.                     push dx
  294.                     call str_push_begin
  295.     write_result_of_operation_return:
  296.                     pop bx
  297.                     pop ax
  298.                     pop di
  299.                     pop si
  300.                     pop bp
  301.                     ret 6
  302.                     endp
  303. ;long_sum(char* dst, char* lhs, char* rhs)
  304. long_sum proc
  305.                     push bp
  306.                     mov bp, sp
  307.                     push si
  308.                     push di
  309.                     push cx
  310.                     push bx
  311.                     push dx
  312.                     push ax
  313.                     mov si, [bp+6] ;lhs value
  314.                     mov di, [bp+4] ;rhs value
  315. ; handling negative values
  316.                     push 0000h ; set (local) set_minus_sign = false
  317.                     push si
  318.                     call get_value_sign
  319.                     mov al, dl
  320.                     push di
  321.                     call get_value_sign
  322.                     mov bl, dl
  323.                     cmp al, 1
  324.                     je long_sum_handling_negative_values_lhs_negative ; if lhs_sign = '-'
  325. ;if lhs_sign = '+'
  326.                     cmp bl, 1
  327.                     jne long_sum_handling_negative_values_end; if rhs_sign = '+'
  328. ;if lhs_sign = '+' && rhs_sign = '-'
  329.                     push offset buffer4
  330.                     push word ptr[bp+4]
  331.                     call strcpy
  332.                     push offset buffer4
  333.                     call str_del_begin
  334.                     mov di, offset buffer4
  335.                     mov word ptr[bp+4], di
  336.                     push word ptr[bp+8]
  337.                     push word ptr[bp+6]
  338.                     push word ptr[bp+4]
  339.                     call long_sub
  340.                     pop ax ; get (local) set_minus_sign
  341.                     jmp long_sum_return
  342.     long_sum_handling_negative_values_lhs_negative:
  343. ;if lhs_sign = '-'
  344.                     push offset buffer3
  345.                     push word ptr[bp+6]
  346.                     call strcpy
  347.                     push offset buffer3
  348.                     call str_del_begin
  349.                     mov si, offset buffer3
  350.                     mov word ptr[bp+6], si
  351.                     cmp bl, 1
  352.                     je long_sum_handling_negative_values_lhs_negative_rhs_negative
  353. ; if lhs_sign = '-' && rhs_sign = '+'
  354.                     push word ptr[bp+8]
  355.                     push word ptr[bp+4]
  356.                     push word ptr[bp+6]
  357.                     call long_sub
  358.                     pop ax ; get (local) set_minus_sign
  359.                     jmp long_sum_return
  360.     long_sum_handling_negative_values_lhs_negative_rhs_negative:
  361. ; if lhs_sign = '-' && rhs_sign = '-'
  362.                     push offset buffer4
  363.                     push word ptr[bp+4]
  364.                     call strcpy
  365.                     push offset buffer4
  366.                     call str_del_begin
  367.                     mov di, offset buffer4
  368.                     mov word ptr[bp+4], di
  369.                     pop ax
  370.                     push 0001h ; set (local) set_minus_sign = true
  371.     long_sum_handling_negative_values_end:
  372.                     mov cl, byte ptr[si+1]
  373.                     cmp cl , byte ptr[di+1]
  374.                     jl long_sum_start
  375.     long_sum_swap_pointers:
  376.                     mov si, [bp+4]
  377.                     mov di, [bp+6]
  378.                     xor cx,cx
  379.     long_sum_start:
  380. ;saving di
  381.                     push di
  382. ;di = biggest_string.end()-1, si = smallest_string.end()-1
  383.                     mov cl, byte ptr[di+1]
  384.                     add di, cx
  385.                     inc di
  386.                     mov cl, byte ptr[si+1]
  387.                     add si, cx
  388.                     inc si
  389.  
  390.     long_sum_small_loop:
  391. ; al = int(*si)
  392.                     mov al, byte ptr[si]
  393.                     push ax
  394.                     call convert_char_to_int
  395.                     mov ax, dx
  396. ; bl = int(*di)
  397.                     mov bl, byte ptr[di]
  398.                     push bx
  399.                     call convert_char_to_int
  400.                     mov bx, dx
  401. ;al = al + bl + carry_buffer
  402.                     add al, bl
  403.                     add al, carry_buffer
  404. ;res.push_begin(al)
  405.                     push word ptr [bp+8]
  406.                     push ax
  407.                     push offset carry_buffer
  408.                     call write_result_of_operation
  409.                     dec si
  410.                     dec di
  411.                     loop long_sum_small_loop
  412. ;restoring di in si
  413.                     pop si
  414. ; cx = biggest_string.size()-(biggest_string.end()-1-di)
  415.                     mov cl, byte ptr[si+1]
  416.                     mov ax, si
  417.                     add ax, cx
  418.                     inc ax
  419.                     sub ax, di
  420.                     sub cl, al
  421.                     cmp cx, 0
  422.                     je long_sum_write_carry_buffer_end
  423.     long_sum_end_loop:
  424.                     xor ax,ax
  425.                     mov bl, byte ptr[di]
  426.                     push bx
  427.                     call convert_char_to_int
  428.                     mov bx, dx
  429. ;al = al + bl + carry_buffer
  430.                     add al, bl
  431.                     add al, carry_buffer
  432. ;res.push_begin(al)
  433.                     push word ptr [bp+8]
  434.                     push ax
  435.                     push offset carry_buffer
  436.                     call write_result_of_operation
  437.                     dec di
  438.                     loop long_sum_end_loop
  439.                     pop ax ; get (local)set_minus_sign
  440.                     cmp al, 1
  441.                     jne long_sum_return
  442.                     push word ptr[bp+8]
  443.                     push 0045
  444.                     call str_push_begin
  445.                     jmp long_sum_return
  446.     long_sum_write_carry_buffer_end:
  447.                     cmp carry_buffer, 0
  448.                     je long_sum_writting_minus_sign_begin
  449.                     push word ptr [bp+8]
  450.                     mov al, carry_buffer
  451.                     push ax
  452.                     push offset carry_buffer
  453.                     call write_result_of_operation
  454.     long_sum_writting_minus_sign_begin:
  455. ; writting minus sign if needed
  456.                     pop ax ; get (local)set_minus_sign
  457.                     cmp al, 1
  458.                     jne long_sum_return
  459.                     push word ptr[bp+8]
  460.                     push 0045
  461.                     call str_push_begin
  462.     long_sum_return:
  463.                     mov carry_buffer, 0
  464.                     pop ax
  465.                     pop dx
  466.                     pop bx
  467.                     pop cx
  468.                     pop di
  469.                     pop si
  470.                     pop bp
  471.                     ret 6
  472.                     endp
  473. ;byte long_cmp(byte* lhs, byte* rhs)
  474. ; dx = 0 - lhs < rhs
  475. ; dx = 1 - lhs = rhs
  476. ; dx = 2 - lhs > rhs
  477. long_cmp proc
  478.                     push bp
  479.                     mov bp, sp
  480.                     push si
  481.                     push di
  482.                     push cx
  483.                     push ax
  484.                     push bx
  485.                     mov si, [bp+6]
  486.                     mov di, [bp+4]
  487.                     mov cl, byte ptr[si+1]
  488.                     cmp cl, byte ptr[di+1]
  489.                     jl long_cmp_return_0
  490.                     jg long_cmp_return_2
  491.                     add si, 2
  492.                     add di, 2
  493.     long_cmp_loop:
  494.                     mov al, byte ptr [si]
  495.                     push ax
  496.                     call convert_char_to_int
  497.                     mov ax, dx
  498.                     mov bl, byte ptr [di]
  499.                     push bx
  500.                     call convert_char_to_int
  501.                     mov bx, dx
  502.                     cmp al, bl
  503.                     jg long_cmp_return_2
  504.                     jl long_cmp_return_0
  505.                     inc si
  506.                     inc di
  507.                     loop long_cmp_loop
  508.                     mov dx, 1
  509.                     jmp long_cmp_return
  510.     long_cmp_return_0:
  511.                     mov dx, 0
  512.                     jmp long_cmp_return
  513.     long_cmp_return_2:
  514.                     mov dx, 2
  515.     long_cmp_return:
  516.                     pop bx
  517.                     pop ax
  518.                     pop cx
  519.                     pop di
  520.                     pop si
  521.                     pop bp
  522.                     ret 4
  523.                     endp
  524. ; long_sub(char* res, char* lhs, char* rhs) ~ res = lhs - rhs
  525. long_sub proc
  526.                     push bp
  527.                     mov bp, sp
  528.                     push si
  529.                     push di
  530.                     push cx
  531.                     push ax
  532.                     push bx
  533.                     mov si, [bp+6] ;lhs string
  534.                     mov di, [bp+4] ;rhs string
  535. ;handling negative values
  536.                     push word ptr[bp+6]
  537.                     call get_value_sign
  538.                     mov al, dl
  539.                     push word ptr[bp+4]
  540.                     call get_value_sign
  541.                     mov bl, dl
  542.                     cmp al, 1
  543.                     je long_sub_handling_negative_values_lhs_negative ; if lhs_sign = '-'
  544. ;if lhs_sign = '+'
  545.                     cmp bl, 1
  546.                     jne long_sub_handling_negative_values_end ; if lhs_sign = '+' && rhs_sign = '+'
  547. ;if lhs_sign = '+' && rhs_sign = '-'
  548.                     push offset buffer4
  549.                     push word ptr[bp+4]
  550.                     call strcpy
  551.                     push offset buffer4
  552.                     call str_del_begin
  553.                     push word ptr[bp+8]
  554.                     push word ptr[bp+6]
  555.                     push offset buffer4
  556.                     call long_sum
  557.                     jmp long_sub_return
  558.     long_sub_handling_negative_values_lhs_negative:
  559. ; if lhs_sign = '-'
  560.                     cmp bl, 1
  561.                     je long_sub_handling_negative_values_lhs_negative_rhs_negative ; if rhs_sign = '-'
  562. ;if lhs_sign = '-' && rhs_sign = '+'
  563. ; adding '-' to copied rhs and call long_sum
  564.                     push offset buffer4
  565.                     push word ptr[bp+4]
  566.                     call strcpy
  567.                     push offset buffer4
  568.                     push 0045 ; '-'
  569.                     call str_push_begin
  570.                     push word ptr[bp+8]
  571.                     push word ptr[bp+6]
  572.                     push offset buffer4
  573.                     call long_sum
  574.                     jmp long_sub_return
  575.     long_sub_handling_negative_values_lhs_negative_rhs_negative:
  576. ; if lhs_sign = '-' && rhs_sign = '-'
  577.                     push offset buffer3
  578.                     push word ptr[bp+6]
  579.                     call strcpy
  580.                     push offset buffer3
  581.                     call str_del_begin
  582.                     mov si, di
  583.                     mov di, offset buffer3
  584.                     mov word ptr[bp+4], di
  585.                     push offset buffer4
  586.                     push si
  587.                     call strcpy
  588.                     push offset buffer4
  589.                     call str_del_begin
  590.                     mov si, offset buffer4
  591.                     mov word ptr[bp+6], si
  592.     long_sub_handling_negative_values_end:
  593.                     push 0000h ; (local) set_minus_sign = false
  594.                     push si
  595.                     push di
  596.                     call long_cmp
  597.                     cmp dx, 1
  598.                     je long_sub_return_0
  599.                     jg long_sub_start
  600.                     pop si; getting (local) set_minus_sign
  601.                     push 0001h ; (local) set_minus_sign = true
  602. ; swap pointers
  603.                     mov si, [bp+4]
  604.                     mov di, [bp+6]
  605.     long_sub_start:
  606.                    
  607.                     push si ; (local) saving biggest value pointer
  608. ; si = biggest_value.end()-1, di = smallest_value.end()-1
  609.                     mov cl, byte ptr[si+1]
  610.                     add si, cx
  611.                     inc si
  612.                     mov cl, byte ptr[di+1]
  613.                     add di, cx
  614.                     inc di
  615.     long_sub_small_loop:
  616. ; al = int(*si)
  617.                     mov al, byte ptr[si]
  618.                     push ax
  619.                     call convert_char_to_int
  620.                     mov ax, dx
  621. ; bl = int(*di)
  622.                     mov bl, byte ptr[di]
  623.                     push bx
  624.                     call convert_char_to_int
  625.                     mov bx, dx
  626.                     add bl, carry_buffer
  627.                     cmp al, bl
  628.                     jl long_sub_small_loop_carry
  629.     long_sub_small_loop_not_carry:
  630.                     mov carry_buffer, 0
  631.                     jmp long_sub_small_loop_continue
  632.     long_sub_small_loop_carry:
  633.                     mov carry_buffer, 1
  634.                     cmp is_hex_algebra, 1
  635.                     je long_sub_small_loop_carry_hex
  636.     long_sub_small_loop_carry_dec:
  637.                     add al,10
  638.                     jmp long_sub_small_loop_continue
  639.     long_sub_small_loop_carry_hex:
  640.                     add al,0fh
  641.     long_sub_small_loop_continue:
  642.                     sub al, bl
  643.                     push word ptr[bp+8]
  644.                     push ax
  645.                     push offset buffer1 + 1
  646.                     call write_result_of_operation
  647.                     dec si
  648.                     dec di
  649.                     loop long_sub_small_loop
  650. ; di = &biggest_value
  651.                     pop di
  652. ; cx = biggest_string.size()-(biggest_string.end()-1-si)
  653.                     mov cl, byte ptr[di+1]
  654.                     mov ax, di
  655.                     add ax, cx
  656.                     inc ax
  657.                     sub ax, si
  658.                     sub cl, al
  659.                     cmp cx, 0
  660.                     je long_sub_write_sign
  661.     long_sub_end_loop:
  662. ; al = int(*si)
  663.                     mov al, byte ptr[si]
  664.                     push ax
  665.                     call convert_char_to_int
  666.                     mov ax, dx
  667. ; bl = 0
  668.                     xor bx, bx
  669.                     add bl, carry_buffer
  670.                     cmp al, bl
  671.                     jl long_sub_end_loop_carry
  672.     long_sub_end_loop_not_carry:
  673.                     mov carry_buffer, 0
  674.                     jmp long_sub_end_loop_continue
  675.     long_sub_end_loop_carry:
  676.                     mov carry_buffer, 1
  677.                     cmp is_hex_algebra, 1
  678.                     je long_sub_end_loop_carry_hex
  679.     long_sub_end_loop_carry_dec:
  680.                     add al,10
  681.                     jmp long_sub_end_loop_continue
  682.     long_sub_end_loop_carry_hex:
  683.                     add al,0fh
  684.     long_sub_end_loop_continue:
  685.                     sub al, bl
  686.                     push word ptr[bp+8]
  687.                     push ax
  688.                     push offset buffer1 + 1
  689.                     call write_result_of_operation
  690.                     dec si
  691.                     loop long_sub_end_loop
  692.     long_sub_write_sign:
  693. ; restoring (local) set_minus_sign in dx
  694.                     push word ptr [bp+8]
  695.                     call str_clear_leading_zeroes
  696.                     pop dx
  697.                     cmp dx, 1
  698.                     jne long_sub_return
  699.                     push word ptr[bp+8]
  700.                     mov ax, 45 ; ax = '-'
  701.                     push ax
  702.                     call str_push_begin
  703.                     jmp long_sub_return
  704.     long_sub_return_0:
  705. ; res = "0"
  706.                     pop dx
  707.                     mov si, [bp+8]
  708.                     mov byte ptr[si+1],1
  709.                     mov byte ptr[si+2],48
  710.     long_sub_return:
  711.                     mov carry_buffer, 0
  712.                     mov byte ptr[offset buffer1 + 1], 0
  713.                     pop bx
  714.                     pop ax
  715.                     pop cx
  716.                     pop di
  717.                     pop si
  718.                     pop bp
  719.                     ret 6
  720.                     endp
  721. ; ~ long_multiply(char* res, char* lhs, char* rhs)
  722. long_multiply proc
  723.                     push bp
  724.                     mov  bp, sp
  725.                     push ax
  726.                     push bx
  727.                     push cx
  728.                     push dx
  729.                     push si
  730.                     push di
  731. ;setting result to 0
  732.                     mov si, [bp+8]
  733.                     mov byte ptr [si+1], 1
  734.                     mov byte ptr [si+2], 48
  735. ;loading lhs and rhs
  736.                     mov di, [bp+4]
  737.                     mov si, [bp+6]
  738. ;check does first argument eq 0
  739.                     push si
  740.                     call is_zero
  741.                     cmp ax, 1
  742.                     je long_multiply_return
  743. ;check does second argument eq 0
  744.                     push di
  745.                     call is_zero
  746.                     cmp ax, 1
  747.                     je long_multiply_return
  748. ;handling negative values
  749.                     push 0000h ; (local)set_minus_sign = false
  750.                     push si
  751.                     call get_value_sign
  752.                     mov al, dl
  753.                     push di
  754.                     call get_value_sign
  755.                     mov bl, dl
  756.                     cmp al, 1
  757.                     je long_multiply_lhs_negative ; if lhs_sign = '-'
  758.                     cmp bl, 1
  759.                     jne long_multiply_start ;if lhs_sign = '+' && rhs_sign = '+'
  760.     ;if lhs_sign = '+' && rhs_sign = '-'
  761.     ;copying rhs, remember to put '-', deleting '-' in copy
  762.                     pop ax ; get (local)set_minus_sign
  763.                     push 0001; set (local)set_minus_sign = true
  764.                     push offset buffer3
  765.                     push word ptr[bp+4]
  766.                     call strcpy
  767.                     push offset buffer3
  768.                     call str_del_begin
  769.                     mov di, offset buffer3
  770.                     mov word ptr[bp+4], di
  771.                     jmp long_multiply_start
  772.     long_multiply_lhs_negative:
  773.     ;if lhs_sign = '-'
  774.     ;copying lhs, remember to put '-', deleting '-' in copy
  775.                     pop ax ; get (local)set_minus_sign
  776.                     push 0001h ; set (local)set_minus_sign = true
  777.                     push offset buffer3
  778.                     push word ptr[bp+6]
  779.                     call strcpy
  780.                     push offset buffer3
  781.                     call str_del_begin
  782.                     mov si, offset buffer3
  783.                     mov word ptr[bp+6], si
  784.                     cmp bl, 1
  785.                     jne long_multiply_start ; if lhs_sign = '-' && rhs_sign = '+'
  786.     ;if lhs_sign = '-' && rhs_sign = '-'
  787.     ;copying rhs, remember to put '+', deleting '-' in copy
  788.                     pop ax ; get (local)set_minus_sign
  789.                     push 0000; set (local)set_minus_sign = false
  790.                     push offset buffer4
  791.                     push word ptr[bp+4]
  792.                     call strcpy
  793.                     push offset buffer4
  794.                     call str_del_begin
  795.                     mov di, offset buffer4
  796.                     mov word ptr[bp+4], di
  797.     long_multiply_start:
  798. ;moving di to end of rhs string and setting iterations
  799.                     mov cl, byte ptr[di+1]
  800.                     add di, cx
  801.                     inc di
  802.     loop_over_rhs_value:
  803. ;filling buffer1 with 0
  804.                     push ax
  805.                     push di
  806.                     mov di, [bp+4]
  807.                     mov al, byte ptr[di+1]
  808.                     sub al, cl
  809.                     push offset buffer1
  810.                     push ax
  811.                     call strfill_with_zeroes
  812.                     pop di
  813.                     pop ax
  814. ;moving si to end of lhs string and setting iterations for inner loop
  815.                     push cx
  816.                     mov si, [bp+6]
  817.                     mov cl, byte ptr[si+1]
  818.                     add si, cx
  819.                     inc si
  820.                     mov carry_buffer, 0
  821.     loop_over_lhs_value:
  822. ; converting lhs char to integer
  823.                     mov al, [si]
  824.                     push ax
  825.                     call convert_char_to_int
  826.                     mov ax, dx
  827. ; converting rhs char to integer
  828.                     mov bl, [di]
  829.                     push bx
  830.                     call convert_char_to_int
  831.                     mov bx, dx
  832. ;multiply digits and write to buffer1
  833.                     mul bl ; al = al * bl
  834.                     add al, carry_buffer ; al += carry_buffer
  835.                     push offset buffer1
  836.                     push ax
  837.                     push offset carry_buffer
  838.                     call write_result_of_operation
  839.                     dec si  ;iterate over lhs
  840.                     loop loop_over_lhs_value
  841. ;write carry buffer if it != 0
  842.                     cmp carry_buffer, 0
  843.                     je writting_carry_buffer_end
  844.     writting_carry_buffer_start:
  845.                     push offset buffer1
  846.                     mov al, carry_buffer
  847.                     push ax
  848.                     push offset carry_buffer
  849.                     call write_result_of_operation
  850.     writting_carry_buffer_end:
  851.                     pop cx  ;return outter loop iterations
  852. ; long_sum(...) buffer2 = res + buffer1
  853.                     push offset buffer2
  854.                     push word ptr [bp+8]
  855.                     push offset buffer1
  856.                     call long_sum
  857. ; strcpy(...) res = buffer2
  858.                     push word ptr [bp+8]
  859.                     push offset buffer2
  860.                     call strcpy
  861. ; strclear(...) buffer2 = ""
  862.                     push offset buffer2
  863.                     call strclear
  864. ; strclear(...) buffer = ""
  865.                     push offset buffer1
  866.                     call strclear
  867.                     dec di  ;iterate over rhs
  868.                     loop loop_over_rhs_value
  869.                     pop ax ;get (local)set_minus_sign
  870.                     cmp al,  0
  871.                     je long_multiply_return ;if set_minus_sign = false
  872.                     push word ptr[bp+8]
  873.                     push 0045
  874.                     call str_push_begin
  875.     long_multiply_return:
  876.                     mov carry_buffer, 0
  877.                     pop di
  878.                     pop si
  879.                     pop dx
  880.                     pop cx
  881.                     pop bx
  882.                     pop ax
  883.                     pop bp
  884.                     ret 6
  885.                     endp
  886. ; check_string_correctness(char* dst)
  887. check_string_correctness proc
  888.                     push bp
  889.                     mov bp, sp
  890.                     push si
  891.                     push cx
  892.                     push ax
  893.                     mov si, [bp+4]
  894.                     mov cl, byte ptr[si+1]
  895.                     add si, 2
  896.                     cmp byte ptr[si], 45
  897.                     jne check_string_correctness_loop ; *si != '-'
  898.                     inc si
  899.                     dec cx
  900.     check_string_correctness_loop:
  901.                     mov al, byte ptr[si]
  902.                     cmp al, 65
  903.                     jl check_string_correctness_loop_cmp_0 ; al < 'A'
  904.                     cmp al, 70
  905.                     jg error ; al > 'F'
  906.                     mov is_hex_algebra, 1
  907.                     inc si
  908.                     loop check_string_correctness_loop
  909.                     cmp cx,0
  910.                     je check_string_correctness_return
  911.                     check_string_correctness_loop_cmp_0:
  912.                     cmp al, 48
  913.                     jl error ; al < '0'
  914.                     cmp al, 57
  915.                     jg error
  916.                     inc si
  917.                     loop check_string_correctness_loop
  918.                     jmp check_string_correctness_return
  919.     error:
  920.                     println_string <offset strerr>
  921.                     mov ax, 4C00h
  922.                     int 21h
  923.     check_string_correctness_return:
  924.                     pop ax
  925.                     pop cx
  926.                     pop si
  927.                     pop bp
  928.                     ret 2
  929.                     endp
  930.     start:          
  931.                     mov ax, data
  932.                     mov ds, ax
  933.                     xor ax, ax
  934.                     print_string <offset description_string>
  935.                     call newline
  936.                     print_string <offset input_lhs_string>
  937.                     readln_string lhs
  938.                     push offset lhs
  939.                     call check_string_correctness
  940.                     print_string <offset input_rhs_string>
  941.                     readln_string rhs
  942.                     push offset rhs
  943.                     call check_string_correctness
  944. ; output lhs*rhs
  945.                     push offset result
  946.                     push offset lhs
  947.                     push offset rhs
  948.                     call long_multiply
  949.                     print_string <offset multiplication_output_string>
  950.                     print_string <offset result + 2>
  951.                     call newline
  952. ; clear result string
  953.                     push offset result
  954.                     call strclear
  955. ; output lhs+rhs
  956.                     push offset result
  957.                     push offset lhs
  958.                     push offset rhs
  959.                     call long_sum
  960.                     print_string <offset sum_output_string>
  961.                     print_string <offset result + 2>
  962.                     call newline
  963. ; clear result string
  964.                     push offset result
  965.                     call strclear
  966. ; output lhs-rhs
  967.                     push offset result
  968.                     push offset lhs
  969.                     push offset rhs
  970.                     call long_sub
  971.                     print_string <offset sub_output_string>
  972.                     print_string <offset result + 2>
  973.                     mov ax, 4C00h
  974.                     int 21h
  975.  
  976. code ends
  977. end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement