При переделке макроса в процедуру возникла нештатная ситуация - Assembler
Формулировка задачи:
Имеется хорошо работающая программа с макросами:
К сожалению попытка переделать макрос putOdd в процедуру с передачей данных через стек работает неправильно. Входит в бесконечный цикл. Подскажите пожалуйста в чём дело.
.model tiny .data a dw 0 .stack 256h .code .486 numBinOut macro num1 push cx push bx mov bx, [num1] push dx push ax mov cx, 16 call numBinOutCall pop ax pop dx pop bx pop cx endm putOdd macro mov ax,[a] or ax,1010101010101010b mov [a],ax endm main: mov ax,@data mov ds,ax xor ax,ax numBinOut a putOdd numBinOut a mov ah,4Ch int 21h ret numBinOutCall: cicl: xor dx,dx sal bx,1 adc dl,30h mov ah,2 int 21h loop cicl ret 2 end main end
.model tiny .data a dw 0 .stack 256h .code .486 numBinOut macro num1 push cx push bx mov bx, [num1] push dx push ax mov cx, 16 call numBinOutCall pop ax pop dx pop bx pop cx endm putOdd proc pop ax or ax,1010101010101010b push ax endp main: mov ax,@data mov ds,ax xor ax,ax numBinOut a push a call putOdd pop a numBinOut a mov ah,4Ch int 21h ret numBinOutCall: cicl: xor dx,dx sal bx,1 adc dl,30h mov ah,2 int 21h loop cicl ret 2 end main end
Решение задачи: «При переделке макроса в процедуру возникла нештатная ситуация»
textual
Листинг программы
putOdd proc ; pop ax mov bp, sp or word ptr [bp+2],1010101010101010b ; push ax retn endp main: mov ax,@data mov ds,ax xor ax,ax numBinOut a mov al, 0Ah int 29h mov al, 0Dh int 29h push a call putOdd pop a numBinOut a
Объяснение кода листинга программы
Список элементов кода:
- putOdd — процедура, обрабатывающая нечетные числа
- main — основная функция, инициализирующая сегменты данных и стека, а также использующая процедуру putOdd
- @data — сегмент данных, инициализируемый в основной функции main
- ax — регистр, используемый в основной функции main для хранения значения 10 (0Ah) и 13 (0Dh)
- bp — регистр, используемый в процедуре putOdd для хранения указателя на стек
- sp — регистр, используемый в процедуре putOdd для хранения значения стека
- 1010101010101010b — двоичное представление числа 15 (нечетное число), используемое в процедуре putOdd для проверки на нечетность
- int 29h — команда ввода-вывода, используемая в основной функции main для вывода символов в бинарном формате
- a — регистр, используемый в основной функции main для хранения значения 10 (0Ah) и 13 (0Dh), а также для передачи в процедуру putOdd и обратно
- 0Ah — десятичное значение 10 (символ
ж
в кодировке CP-1251), используемое в основной функции main для вывода символа - 0Dh — десятичное значение 13 (символ
з
в кодировке CP-1251), используемое в основной функции main для вывода символа - push a — команда сохранения регистра a на стеке перед вызовом процедуры putOdd
- call — команда вызова процедуры putOdd
- pop a — команда восстановления регистра a из стека после выхода из процедуры putOdd
- numBinOut a — команда вывода значения регистра a в бинарном формате
- int 29h — команда ввода-вывода, используемая в основной функции main для вывода символов в бинарном формате
- 0Ah — десятичное значение 10 (символ
ж
в кодировке CP-1251), используемое в команде numBinOut a для вывода символа - 0Dh — десятичное значение 13 (символ
з
в кодировке CP-1251), используемое в команде numBinOut a для вывода символа