; (c) xrnd [2010] [http://asmworld.ru/] ; vararg.asm - пример реализации процедур с переменным количеством параметров. use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h push 2 ;Второе число push 10 ;Первое число push 2 ;Количество чисел = 2 call average ;Вызов процедуры average add sp,6 ;Восстановление стека push -5 ;Третье число push 99 ;Второе число push 0 ;Первое число push 3 ;Количество чисел = 3 call average ;Вызов процедуры average add sp,8 ;Восстановление стека push 0 ;Последний параметр = 0 push str_3 ;Строка 3 push str_2 ;Строка 2 push str_1 ;Строка 1 call print_strs ;Вызов процедуры print_strs push 0 ;Последний параметр = 0 push s_pak ;Строка 'Press any key...' call print_strs ;Вызов процедуры print_strs add sp,12 ;Восстановление стека mov ah,8 ;\ int 21h ;/ Ввод символа без эха mov ax,4C00h ;\ int 21h ;/ Завершение программы ;--------------------------------------------------------------------- ;Данные str_1 db 'Hello $' str_2 db 'asmworld.ru!$' str_3 db 13,10,'$' s_pak db 'Press any key...$' ;--------------------------------------------------------------------- ;Процедура вычисления среднего арифметического. ;Первый параметр - количество чисел, остальные параметры - числа. ;Возвращает значение в регистре AX average: push bp ;Сохранение BP mov bp,sp ;BP=SP push cx ;Сохранение других используемых регистров push dx push si mov cx,[bp+4] ;CX=первый параметр mov si,6 ;SI=6, (BP+SI)=адрес второго параметра xor ax,ax ;AX=0, в AX будет вычисляться сумма чисел jcxz av_ret ;Если CX=0, то выход из процедуры av_lp: add ax,[bp+si] ;Прибавление к AX очередного параметра из стека add si,2 ;SI=SI+2, (BP+SI)=адрес следующего параметра loop av_lp ;Команда цикла cwd ;DX:AX=AX idiv word[bp+4] ;Деление суммы на первый параметр av_ret: pop si ;Восстановление регистров pop dx pop cx pop bp ret ;Возврат из процедуры ;--------------------------------------------------------------------- ;Процедура вывода нескольких строк на консоль. ;Параметры - адреса строк. Последний параметр должен быть равен 0 print_strs: push bp ;Сохранение BP mov bp,sp ;BP=SP push ax ;Сохранение других используемых регистров push dx push si mov si,4 ;SI=4, (BP+SI)=адрес первого параметра mov ah,9 ;Функция DOS 09h - вывод строки pss_lp: mov dx,[bp+si] ;DX=очередной параметр test dx,dx ;Проверка DX jz pss_ret ;Если DX=0, то выход из процедуры int 21h ;Обращение к функции DOS add si,2 ;SI=SI+2, (BP+SI)=адрес следующего параметра jmp pss_lp ;Переход к началу цикла pss_ret: pop si ;Восстановление регистров pop dx pop ax pop bp ret ;Возврат из процедуры