Advertisement
stupid_pro

aboba

Apr 28th, 2024 (edited)
990
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; Читаем массив char-ов cо стандартного потока ввода
  2. ; в динамическую память.
  3. ; считывание прекращается в тот момент, когда в потоке ввода встретилось char
  4. ; со значением 0.
  5. ; Память выделяем макросом new.
  6.  
  7. ;мой основной код для прака
  8.  
  9. include console.inc
  10.  
  11. ALLONG_SIZE equ 2
  12. ZERO_CODE equ 48
  13. SLASH equ 92
  14.  
  15. .data
  16.     array_size    dd 0
  17.     array_pointer dd 0
  18.  
  19. .code
  20.  
  21.     ;
  22.     ; параметры:
  23.     ; 1. параметр указатель на начало массива.
  24.     ; 2. указатель на размер массива.
  25.     ; возвращаемое значение
  26.     ; 0 - всё хорошо
  27.     ;
  28.  
  29. read_array proc
  30.     push ebp
  31.     mov ebp, esp
  32.  
  33.     ;
  34.     ; зарезервируем место на стеке,
  35.     ; для хранения размера выделенной памяти для массива
  36.     ; выделим 4 байта, в дальнейшем к ним обращаться как
  37.     ; [ebp - 4]
  38.     ;выделяем 4 байта: в младшем байте будет лежать наш char, в остальных трех будут лежать нули
  39.     ;
  40.  
  41.     sub esp, 20
  42.  
  43.     ;
  44.     ; В регистре ebx будем сохранять текущий размер считываемого  массива.
  45.     ; в edi - будем хранить текущий адрес массива
  46.     ; в esi - считанный элемент массива
  47.     ;
  48.  
  49.     push ebx
  50.     push esi
  51.     push edi
  52.  
  53.     mov ebx, 0
  54.  
  55.     ;
  56.     ; Делаем размер выделенной памяти
  57.     ; равным 0 изначально.
  58.     ; edi указатель на массив проинициализируем 0, чтобы dispose
  59.     ; не  вызывать.
  60.     ;
  61.  
  62.     mov dword ptr [ebp - 4], 0
  63.     mov dword ptr [ebp - 8], 0
  64.     mov dword ptr [ebp - 12], 0
  65.     mov dword ptr [ebp - 16], 0
  66.     mov dword ptr [ebp - 20], 0
  67.  
  68.     mov edi, 0
  69.  
  70. read_elms_loop:
  71.  
  72.     ;
  73.     ;будем записывать чары в регистр dl
  74.     ;
  75.  
  76.     outstrln "input elm: "
  77.     inchar dl
  78.     outstr "read elm: "
  79.     outcharln dl
  80.  
  81.     ;
  82.     ;записываем в esi значение регистра dl, пополненное нулями
  83.     ;
  84.  
  85.     movzx esi, dl
  86.  
  87.     cmp esi, ZERO_CODE
  88.     je after_read_elms_loop
  89.  
  90.       mov ecx, 8
  91.  
  92. make_fin_reg:
  93.     shl dword ptr [ebp - 16], 1
  94.     rcl dword ptr [ebp - 20], 1
  95.     loop make_fin_reg
  96.     add dword ptr [ebp - 16], esi
  97.     cmp dword ptr [ebp - 20], '/-:f'
  98.     jne not_slash_pered_fin
  99.     cmp dword ptr [ebp - 12], 1
  100.     je not_fin
  101.  
  102. not_slash_pered_fin:
  103.     mov eax, '0-:f'
  104.     and eax, 0ffffffh
  105.     and dword ptr [ebp - 20], 0ffffffh
  106.     cmp dword ptr [ebp - 20], eax
  107.     jne not_fin
  108.     cmp dword ptr [ebp - 16], 'in:-'
  109.     jne not_fin
  110.     jmp after_read_elms_loop
  111.  
  112. not_fin:
  113.  
  114.     ;проверка /
  115.  
  116.     cmp esi, '/'
  117.     jne not_slash
  118.     cmp dword ptr [ebp - 8], 1
  119.     je not_one_slash
  120.     mov dword ptr [ebp - 8], 1
  121.     mov dword ptr [ebp - 12], 1
  122.     jmp read_elms_loop
  123.  
  124. not_one_slash:
  125.     mov dword ptr [ebp - 8], 0
  126.     mov dword ptr [ebp - 12], 0
  127.  
  128. not_slash:
  129.     mov dword ptr [ebp - 8], 0
  130.  
  131.     ; cmp esi, SLASH
  132.     ; outintln esi
  133.     ; jne routine
  134.  
  135. ; first_slash:
  136. ;     outstr "input elem: (we got first slash)"
  137. ;     inchar dl
  138. ;     outstr "read elm: "
  139. ;     outcharln dl
  140.  
  141. ;     movzx esi, dl
  142.  
  143. ;     cmp esi, ZERO_CODE
  144. ;     je after_read_elms_loop
  145.  
  146. ;     cmp esi, '\'
  147. ;     je routine
  148.  
  149. ; routine:
  150.  
  151.     ;
  152.     ; проверяем есть ли место куда положить очередной элемент
  153.     ; если нет, то запускаем выделение памяти
  154.     ;
  155.  
  156.     cmp ebx, [ebp - 4]
  157.     jb mem_enough
  158.     outstrln "allong mem"
  159.  
  160.     ;
  161.     ; на сколько байт будем удлиннять память.
  162.     ; удлинняем на 2 элемента, каждый по 4 байта.
  163.     ; Для этого пересчитываем размер из элементов в байты.
  164.     ; затем прибавляем то, на сколько увеличиваем размер памяти.
  165.     ; и проверяем на переполнение.
  166.     ; эта часть кода отвечает за ситуацию, когда текущий размер памяти >= выделенному
  167.     ;
  168.  
  169.     mov eax, 1 ; в eax помещаем 4 - размер одного элемента
  170.     mul ebx ; mul - умножение на eax того, что мы передали результат в EDX:EAX
  171.     ; теперь в eax хранится число байтов, которое выделено под элементы
  172.     add eax, ALLONG_SIZE ; allong_size = 2
  173.     jc process_overflow ;jc - jump carry flag
  174.  
  175.     ;
  176.     ; Сохраним новый размер в переменную,
  177.     ; где мы храним размер.
  178.     ;
  179.  
  180.     add  dword ptr [ebp - 4], ALLONG_SIZE
  181.  
  182.     ;
  183.     ; Здесь как параметр макроса передаём размер, который лежит в еах,
  184.     ; сам макрос после работы в регистре eax вернёт
  185.     ; новый указатель на выделенную память.
  186.     ; если памяти нет, то вернётся 0
  187.     ;
  188.  
  189.     push ebx
  190.  
  191.     outstr "New memory allocation size: "
  192.     outintln eax
  193.  
  194.     new eax
  195.     cmp eax, 0
  196.     je process_out_of_mem
  197.  
  198.     outstr "New pointer to array: "
  199.     outintln eax
  200.  
  201.     outstr "Old pointer to array: "
  202.     outintln edi
  203.  
  204.     pop ebx
  205.  
  206.     ;
  207.     ; переписываем старую память в новую.
  208.     ;
  209.  
  210.     mov ecx, 0
  211.  
  212. copy_elms_loop:
  213.  
  214.     cmp ecx, ebx
  215.     jae after_copy_elms_loop ; прыжок, если всё перекопировали
  216.  
  217.     mov dl, [edi + ecx * 1]
  218.     mov [eax + ecx * 1], dl
  219.  
  220.     inc ecx
  221.     jmp copy_elms_loop
  222.  
  223. after_copy_elms_loop:
  224.  
  225.     ;
  226.     ; меняем указатели и освобождаем старую память.
  227.     ;
  228.  
  229.     xchg eax, edi
  230.     cmp eax, 0
  231.  
  232.     je mem_enough
  233.  
  234.     push ebx
  235.     dispose eax
  236.     pop ebx
  237.  
  238.  
  239.  
  240. mem_enough:
  241.  
  242.     ;
  243.     ; Помещаем новый элемент в выделенную память.
  244.     ;
  245.  
  246.     mov edx, esi
  247.  
  248.     mov [edi + 1 * ebx], edx
  249.  
  250.     inc ebx
  251.  
  252.     jmp read_elms_loop
  253.  
  254. after_read_elms_loop:
  255.     outstrln "The program has finished"
  256.     ;
  257.     ; normal finishing
  258.     ;
  259.  
  260.     ;
  261.     ; возвращаем адрес массива
  262.     ;
  263.  
  264.     mov esi, [ebp + 8]
  265.     mov [esi], edi
  266.  
  267.     ;
  268.     ; возвращаем размер массива
  269.     ;
  270.  
  271.     mov esi, [ebp + 12]
  272.     mov [esi], ebx
  273.  
  274.     pop edi
  275.     pop esi
  276.     pop ebx
  277.  
  278.     mov eax, 0
  279.  
  280.     mov esp, ebp
  281.  
  282.     pop ebp
  283.  
  284.     ret 4 + 4
  285.  
  286. process_overflow:
  287.  
  288.     dispose edi ; чистим выделенную память
  289.  
  290.     pop edi
  291.     pop esi
  292.     pop ebx
  293.  
  294.     mov eax, 1
  295.     mov esp, ebp
  296.     pop ebp
  297.  
  298.     ret 4 + 4
  299.  
  300. process_out_of_mem:
  301.  
  302.     dispose edi ; чистим выделенную память
  303.     pop edi
  304.     pop esi
  305.     pop ebx
  306.  
  307.     mov eax, 2
  308.  
  309.     mov esp, ebp
  310.     pop ebp
  311.     ret 4 + 4
  312.  
  313. read_array endp
  314.  
  315.  
  316. print_array proc
  317.  
  318.     push ebp
  319.     mov ebp, esp
  320.     push edi
  321.  
  322.  
  323.     mov edi, [ebp + 8]
  324.     mov ecx, 0
  325.  
  326. loop_print_arr:
  327.  
  328.  
  329.     cmp ecx, [ebp + 12]
  330.  
  331.     jae after_loop_print_arr
  332.  
  333.     outchar byte ptr [edi + 1 * ecx]
  334.  
  335.     inc ecx
  336.  
  337.     jmp loop_print_arr
  338.  
  339. after_loop_print_arr:
  340.  
  341.     pop edi
  342.  
  343.     pop ebp
  344.  
  345.     ret 4 + 4
  346.  
  347.     print_array endp
  348.  
  349. start:
  350.  
  351.    push offset array_size
  352.    push offset array_pointer
  353.    call read_array
  354.  
  355.    outstr "array read, size: "
  356.    outintln array_size
  357.  
  358.    push array_size
  359.    push array_pointer
  360.    call print_array
  361.  
  362.    exit 0
  363. end start
  364.  
  365.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement