Использование стека в подпрограмме - Assembler

Узнай цену своей работы

Формулировка задачи:

Помогите пожалуйста найти ошибку,она скорее всего произошла при передаче параметров через стек. Программа выводит 11223344, вместо 15263748
 .model small
      .stack 100h
      .data
    mas db '1','2','3','4','5','6','7','8'
    n dw 4
       .code
 
start:  mov ax,@data
    mov ds,ax
    xor ax,ax
        
        mov ax,offset mas
        push ax      
        mov bp,'0'     ;
        push bp        ; загружаем указатель стека
 
        mov di,4    
    mov si,0
 
        push di
        push si  
        
        CALL POSSY
        jmp fin         ; переход к выходу
 
POSSY:               
        mov si,[bp]+4   ; адрес возврата и инструкция push bp занимают 4 байта
        mov di,[bp]+6
        mov bx,[bp]+8   
        
        mov ah,2
                
circle: 
        xor dx,dx
    mov dl,[bx+si]
    int 21h
        xor dx,dx
 
    mov dl,[bx+di]
    int 21h
    inc si
    inc di
    
    cmp si,n
    jne circle        ; преход, если не равно
        RET

fin:    mov ax,4c00h
    int 21h
 
    end start

Решение задачи: «Использование стека в подпрограмме»

textual
Листинг программы
.model small
.stack 100h
.data
mas db '1','2','3','4','5','6','7','8'
n dw 4
.code
 
start: mov ax,@data
mov ds,ax
xor ax,ax
 
mov ax,offset mas
push ax
 
mov di,4
mov si,0
 
push di
push si
 
CALL POSSY
add sp, 6
jmp short fin ; переход к выходу
 
POSSY:
mov bp, sp
mov si,[bp]+2 ; адрес возврата и инструкция push bp занимают 4 байта
mov di,[bp]+4
mov bx,[bp]+6
mov ah,2
 
circle:
xor dx,dx
mov dl,[bx+si]
int 21h
xor dx,dx
 
mov dl,[bx+di]
int 21h
inc si
inc di
 
cmp si,n
jne circle ; преход, если не равно
RET
 
 
fin: mov ax,4c00h
int 21h
 
end start

Объяснение кода листинга программы

  1. .model small - устанавливает модель памяти, в которой используется сегментный способ адресации и сегмент данных имеет размер 16 бит
  2. .stack 100h - определяет размер стека в 100 байт
  3. .data - сегмент данных
  4. mas db '1','2','3','4','5','6','7','8' - определение строки mas в сегменте данных
  5. n dw 4 - определение переменной n в сегменте данных, содержащей число 4
  6. .code - сегмент кода
  7. start: ... - начало выполнения программы, изначально находится в сегменте кода
  8. mov ax,@data - загрузка сегмента данных в регистр AX
  9. mov ds,ax - установка сегмента данных в регистр DS
  10. xor ax,ax - очистка регистра AX
  11. mov ax,offset mas - загрузка адреса строки mas в регистр AX
  12. push ax - помещение значения регистра AX в стек
  13. mov di,4 - инициализация регистра DI значением 4
  14. mov si,0 - инициализация регистра SI значением 0
  15. push di - помещение значения регистра DI в стек
  16. push si - помещение значения регистра SI в стек
  17. CALL POSSY - вызов подпрограммы POSSY
  18. add sp, 6 - удаление из стека 6 байт (2 байта для возвращаемого адреса и 4 байта для регистров DI и SI)
  19. jmp short fin - переход к подпрограмме fin
  20. POSSY: ... - начало подпрограммы POSSY
  21. mov bp, sp - загрузка значения регистра SP в регистр BP
  22. mov si,[bp]+2 - загрузка значения регистра SI из стека с смещением 2 байта (в стеке сначала идут адрес возврата и инструкция push bp)
  23. mov di,[bp]+4 - загрузка значения регистра DI из стека с смещением 4 байта
  24. mov bx,[bp]+6 - загрузка значения регистра BX из стека с смещением 6 байта
  25. mov ah,2 - установка регистра AH равным 2
  26. circle: ... - начало цикла circle
  27. xor dx,dx - очистка регистра DX
  28. mov dl,[bx+si] - загрузка значения байта из памяти по адресу [BX+SI] в регистр DL
  29. int 21h - вывод значения регистра DL на экран
  30. xor dx,dx - очистка регистра DX
  31. mov dl,[bx+di] - загрузка значения байта из памяти по адресу [BX+DI] в регистр DL
  32. int 21h - вывод значения регистра DL на экран
  33. inc si - увеличение значения регистра SI на 1
  34. inc di - увеличение значения регистра DI на 1
  35. cmp si,n - сравнение значения регистра SI с переменной n
  36. jne circle - если значения не равны, то переход на начало цикла circle
  37. RET - возврат из подпрограммы POSSY
  38. fin: ... - начало подпрограммы fin
  39. mov ax,4c00h - установка регистра AX равным 4C00h (код завершения работы программы)
  40. int 21h - вывод значения регистра AX на экран (завершение работы программы)
  41. end start - конец программы

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.636 из 5
Похожие ответы