Использование стека в подпрограмме - 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
Объяснение кода листинга программы
- .model small - устанавливает модель памяти, в которой используется сегментный способ адресации и сегмент данных имеет размер 16 бит
- .stack 100h - определяет размер стека в 100 байт
- .data - сегмент данных
- mas db '1','2','3','4','5','6','7','8' - определение строки
mas
в сегменте данных - n dw 4 - определение переменной
n
в сегменте данных, содержащей число 4 - .code - сегмент кода
- start: ... - начало выполнения программы, изначально находится в сегменте кода
- mov ax,@data - загрузка сегмента данных в регистр AX
- mov ds,ax - установка сегмента данных в регистр DS
- xor ax,ax - очистка регистра AX
- mov ax,offset mas - загрузка адреса строки
mas
в регистр AX - push ax - помещение значения регистра AX в стек
- mov di,4 - инициализация регистра DI значением 4
- mov si,0 - инициализация регистра SI значением 0
- push di - помещение значения регистра DI в стек
- push si - помещение значения регистра SI в стек
- CALL POSSY - вызов подпрограммы
POSSY
- add sp, 6 - удаление из стека 6 байт (2 байта для возвращаемого адреса и 4 байта для регистров DI и SI)
- jmp short fin - переход к подпрограмме
fin
- POSSY: ... - начало подпрограммы
POSSY
- mov bp, sp - загрузка значения регистра SP в регистр BP
- mov si,[bp]+2 - загрузка значения регистра SI из стека с смещением 2 байта (в стеке сначала идут адрес возврата и инструкция push bp)
- mov di,[bp]+4 - загрузка значения регистра DI из стека с смещением 4 байта
- mov bx,[bp]+6 - загрузка значения регистра BX из стека с смещением 6 байта
- mov ah,2 - установка регистра AH равным 2
- circle: ... - начало цикла
circle
- xor dx,dx - очистка регистра DX
- mov dl,[bx+si] - загрузка значения байта из памяти по адресу [BX+SI] в регистр DL
- int 21h - вывод значения регистра DL на экран
- xor dx,dx - очистка регистра DX
- mov dl,[bx+di] - загрузка значения байта из памяти по адресу [BX+DI] в регистр DL
- int 21h - вывод значения регистра DL на экран
- inc si - увеличение значения регистра SI на 1
- inc di - увеличение значения регистра DI на 1
- cmp si,n - сравнение значения регистра SI с переменной
n
- jne circle - если значения не равны, то переход на начало цикла
circle
- RET - возврат из подпрограммы
POSSY
- fin: ... - начало подпрограммы
fin
- mov ax,4c00h - установка регистра AX равным 4C00h (код завершения работы программы)
- int 21h - вывод значения регистра AX на экран (завершение работы программы)
- end start - конец программы
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д