Положение курсора на экране - 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

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

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

  1. Переменные:
    • BDATA (сегмент данных BIOS)
    • VPAGE (текущая видеостраница)
    • VCPOS (массив положений курсора для 8 в/стр.)
    • Num (строка с числом для вывода)
    • ax, bx, al, bl (регистры процессора)
  2. Макросы:
    • getxy (макрос для получения текущих координат курсора)
  3. Команды:
    • push/pop (для работы со стеком)
    • mov (для перемещения данных между регистрами или регистрами и памятью)
    • lea (для получения адреса памяти)
    • call (для вызова подпрограммы)
    • int (для вызова функции BIOS)
    • xor (для установки регистра в 0 или 1)
    • aam (для деления целого числа на 10)
    • or (для логического ИЛИ двух значений)
    • xchg (для обмена значениями двух регистров)
    • ret (для возврата из подпрограммы)
  4. Действия:
    • Вывод числа на экран (используя функцию BIOS int 21h)
    • Получение текущих координат курсора
    • Преобразование чисел в символы (для вывода на экран)
    • Вывод десятичной и двоичной частей числа (с использованием функции BIOS int 29h)
    • Вывод пробела (с использованием функции BIOS int 29h)
    • Вызов подпрограммы cvt (для преобразования чисел в символы)
    • Использование отладчика (int 3)
    • Вывод строки $ (с использованием функции BIOS int 29h)
    • Использование функции BIOS int 4Ch для выхода из программы
    • Проверка числа на значение меньше 99 (для использования в подпрограмме cvt)

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

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