При переделке макроса в процедуру возникла нештатная ситуация - Assembler

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

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

Имеется хорошо работающая программа с макросами:
.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
К сожалению попытка переделать макрос 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 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

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

Список элементов кода:

  1. putOdd — процедура, обрабатывающая нечетные числа
  2. main — основная функция, инициализирующая сегменты данных и стека, а также использующая процедуру putOdd
  3. @data — сегмент данных, инициализируемый в основной функции main
  4. ax — регистр, используемый в основной функции main для хранения значения 10 (0Ah) и 13 (0Dh)
  5. bp — регистр, используемый в процедуре putOdd для хранения указателя на стек
  6. sp — регистр, используемый в процедуре putOdd для хранения значения стека
  7. 1010101010101010b — двоичное представление числа 15 (нечетное число), используемое в процедуре putOdd для проверки на нечетность
  8. int 29h — команда ввода-вывода, используемая в основной функции main для вывода символов в бинарном формате
  9. a — регистр, используемый в основной функции main для хранения значения 10 (0Ah) и 13 (0Dh), а также для передачи в процедуру putOdd и обратно
  10. 0Ah — десятичное значение 10 (символ ж в кодировке CP-1251), используемое в основной функции main для вывода символа
  11. 0Dh — десятичное значение 13 (символ з в кодировке CP-1251), используемое в основной функции main для вывода символа
  12. push a — команда сохранения регистра a на стеке перед вызовом процедуры putOdd
  13. call — команда вызова процедуры putOdd
  14. pop a — команда восстановления регистра a из стека после выхода из процедуры putOdd
  15. numBinOut a — команда вывода значения регистра a в бинарном формате
  16. int 29h — команда ввода-вывода, используемая в основной функции main для вывода символов в бинарном формате
  17. 0Ah — десятичное значение 10 (символ ж в кодировке CP-1251), используемое в команде numBinOut a для вывода символа
  18. 0Dh — десятичное значение 13 (символ з в кодировке CP-1251), используемое в команде numBinOut a для вывода символа

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

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