Положение курсора на экране - Assembler
Формулировка задачи:
Здравствуйте.
Столкнулся с такой проблемой. Хочу получить положение курсора на экране. Использую для этого функцию 03 прерывания 10h. Но когда взываю это прерывание, на экране "съедается" та строка, которая была до этого выведена.
но при этом, при повторном запуске этой программы из этого же окна командной строки всё получается нормально. всё выводит.
Я уже даже сделал вывод не по 9-й функции 12h прерывания, а с помощью 10h прерывания.
и да, переменная должна быть в сегменте кода.
да, создаю exe файл.
CODE SEGMENT ASSUME CS:CODE, DS:DATA, SS:SSEG Num DB '11111222223333344444555556666677777',10,13,'$' outputAL MACRO push ax push bx push cx push DX mov ah,0Eh mov bh,0d mov bl, 07d mov cx,1d int 10h pop DX pop cx pop bx pop ax ENDM WRITE10 MACRO Seg_var, var local finish, next_symbol push AX push SI push DS mov AX, seg Seg_var mov DS, AX lea SI, var next_symbol: mov Al, [SI] cmp Al, '$' jz finish outputAL inc SI jmp next_symbol finish: pop DS pop SI pop AX ENDM GetCurs Proc near push AX BX CX mov Ah,03h mov Bh,0 int 10h pop CX BX AX ret GetCurs ENDP Main Proc near mov AX, seg DATA mov DS, AX WRITE10 CODE, Num call GetCurs mov Ah, 4Ch int 21h ret Main ENDP CODE ENDS DATA SEGMENT DATA ENDS SSEG SEGMENT STACK DW 200 dup(?) SSEG ENDS end Main
Решение задачи: «Положение курсора на экране»
textual
Листинг программы
.286 .model small BDATA = 40h ; сегмент данных BIOS VPAGE = 62h ; текущая видеостраница VCPOS = 50h ; массив положений курсора для 8 в/стр. getxy macro push bx mov bx, es:[VPAGE] xor bh, bh mov ax, es:VCPOS[bx] pop bx endm .stack .data .code Num DB '11111222223333344444555556666677777',10,13,'$' Main: push BDATA pop es push cs pop ds lea dx, Num mov ah,9 int 21h getxy ; выводим позицию mov bx, ax call cvt ; колонка mov al, 20h int 29h ; выводим пробел mov al, bh call cvt ; строка ; int 3 ; для отладчика xor ax,ax int 16h mov Ah, 4Ch int 21h ; только для чисел меньше 99. cvt: aam ;al div 10, ah - десятки al - единицы or ax, 3030h ; пребразуем в символы xchg ah, al ; меняем местами int 29h ; выводим десятки xchg ah, al int 29h ; выводим единицы ret end Main
Объяснение кода листинга программы
Список элементов кода:
- Переменные:
- BDATA (сегмент данных BIOS)
- VPAGE (текущая видеостраница)
- VCPOS (массив положений курсора для 8 в/стр.)
- Num (строка с числом для вывода)
- ax, bx, al, bl (регистры процессора)
- Макросы:
- getxy (макрос для получения текущих координат курсора)
- Команды:
- push/pop (для работы со стеком)
- mov (для перемещения данных между регистрами или регистрами и памятью)
- lea (для получения адреса памяти)
- call (для вызова подпрограммы)
- int (для вызова функции BIOS)
- xor (для установки регистра в 0 или 1)
- aam (для деления целого числа на 10)
- or (для логического ИЛИ двух значений)
- xchg (для обмена значениями двух регистров)
- ret (для возврата из подпрограммы)
- Действия:
- Вывод числа на экран (используя функцию BIOS int 21h)
- Получение текущих координат курсора
- Преобразование чисел в символы (для вывода на экран)
- Вывод десятичной и двоичной частей числа (с использованием функции BIOS int 29h)
- Вывод пробела (с использованием функции BIOS int 29h)
- Вызов подпрограммы cvt (для преобразования чисел в символы)
- Использование отладчика (int 3)
- Вывод строки
$
(с использованием функции BIOS int 29h) - Использование функции BIOS int 4Ch для выхода из программы
- Проверка числа на значение меньше 99 (для использования в подпрограмме cvt)