Сортировка массива в сборке 8086 16 бит

Я пытаюсь отсортировать массив с помощью функций, которые находят наименьшее число в массиве, а другая меняет местами две переменные. Но по какой-то причине массив не меняется и остается прежним. Я думаю, что у меня проблема со стеком, но я не могу его найти.

Это мой код: извините, он длинный и неорганизованный. Я только начал сборку. `

org 100h
    
     jmp start
        array db 1,9,3,6,3 **;should get 1,2,3,6,9**
        min_in_array dw ?
        
    start: 
       
       lea si, array         
       push 5 
       push si
       call sortArray 
       pop bx
       pop bx
       mov ah, 0
       int 16h
       ret
        

;doesn't work
PROC sortArray
    push bp
    mov bp, sp
    
    mov dx, 0 ;the index
    mov cx, [bp+6];size
    mov di, [bp+4];array  
    
    loop_arr: 
        add di, dx
        push di
        call findMin
        pop di
        
        
        sub di, dx
         
        add di, min_in_array 
        push dx        
        push di
        call swap
        pop di
        pop dx
        sub di, min_in_array
        inc dx
        
        mov ax, [di]
        loop loop_arr
        
   
     mov sp, bp
     pop bp
   
     ret
ENDP sortArray    


;works
PROC findMin
    push bp
    mov bp, sp
    sub sp, 4
    
    mov cx, 0 ;init the counter
    mov di, [bp+4]
    mov al, [bp-2] ;initialising the min save var
    mov al, [di] 
    
    mov bx, [bp-4] ;the index to save
    mov bx, 0
    
    run:
        cmp al, [di] 
        ja change_min 
        cmp cx, 4 ;check if cx is lower than the size of the array
        inc cx ;+1
        inc di ;move forward in the array
        jb run ;check again
        jmp fin ;finished - cx = size
        
    change_min:        
        mov al, [di] ;change the min
        mov bx, cx  ;assign the index
        inc di 
        cmp cx, 4  
        je fin
        inc cx
        jmp run
    
         
    fin: 
        mov sp, bp
        pop bp
        mov cx, 0
        
        mov min_in_array, bx
        ret 
ENDP findMin                               


;function works
PROC swap       
    ;creates fram  
    push    bp
    mov     bp,sp  
    
    sub sp,2 ;make space for local temp 
    mov bx, [bp+6]
    mov cx, [bp+4]
    ;swaping using the temp varaiable
    mov [bp-2], bx
    mov bx, cx
    mov cx, [bp-2]
         
    ;close frame
    mov sp, bp
    pop bp
    ret
ENDP swap  

`

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
0
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У меня проблема со стеком, но я не могу его найти.

Ваше использование стека на самом деле нормально: пролог, эпилог, очистка.
Но есть еще одна вещь, в которой стек хорош, и это сохранение значений регистров. Ваша процедура sortArray зависит от регистра CX, но вы уничтожаете его значение в процедурах findMin и swap!

Вы говорите, что findMin работает, но я вас уверяю, что это не так. Помимо отсутствия сохранения CX и содержания большого количества неиспользуемого кода, findMin всегда обрабатывает 5 элементов, даже несмотря на то, что предоставленный адрес перемещается вверх с каждым вызовом, что означает, что вы обрабатываете мусор, который следует за исходным массивом в памяти. Более того, результат, который вы сохраняете в переменной min_in_array, является смещением в несортированном разделе массива, но после возврата sortArray будет использовать это же значение в качестве смещения в исходном массиве. Нельзя так работать...

Вы говорите, что обмен работает, но я уверяю вас, что это не так. То, что вы предоставляете этой процедуре, является смещением в исходном массиве и (ошибочно рассчитанным) адресом в исходном массиве. Вы извлекаете эти аргументы из стека и только меняете их местами в регистрах, не более того. Вы никогда не читаете/записываете в массив, поэтому обмен не происходит.

Посмотрите, указывает ли следующий код в правильном направлении:

    add  di, dx
    push cx         ; Number of elements in the unsorted partition
    push di         ; Address of the start of the unsorted partition
    call findMin    ; -> AX (BL CX SI)
    pop  di
    pop  cx

    push ax         ; Address of the Min from the unsorted partition
    push di         ; Address of the start of the unsorted partition
    call swap
    ...

; IN () OUT (ax) MOD (bl,cx,si)
PROC findMin
    push bp
    mov  bp, sp
    mov  cx, [bp + 6]
    mov  si, [bp + 4]
  min:
    mov  bl, [si] 
    mov  ax, si
  run:
    dec  cx
    jz   done
    inc  si
    cmp  bl, [si] 
    jb   run
    jmp  min                 ; Go change min
  done:
    pop  bp
    ret 
ENDP findMin

Другие вопросы по теме