Соединение объектных модулей в головной - Assembler

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

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

Здравствуйте. Есть программа, которая написана в одном объектном модуле, и есть необходимость разделить ее на несколько модулей. В итоге из одного модуля получилось 3, public и extrn были прописаны в нужных местах (как мне кажется). Но при компиляции всего этого добра в основную программу, она стала работать неправильно. По идее, на экран должно выдаваться текущее системное время (что она и делала ранее), а вместо этого на экране непонятные символы. Что не так? Чего не хватает в каждом модуле? Собстна, вот код. модуль t1.asm
data segment public
exit                db 0  ;переменная выхода
tick                db 0  ;таймер 1 Сh
clock_out           db 0  ;переменная таймера
old_cs_1ch          dw ?  ;старый адрес 1ch
old_ip_1ch          dw ? 
 
public exit, tick, clock_out
extrn NEW_1CH
extrn CLS 
extrn OUT_CLOCK
data ends
 
code segment public
assume cs:code, ds:data
start:  ;НАЧАЛО ОСНОВНОЙ ПРОГРАММЫ
    mov ax, data
    mov ds, ax
    mov ah, 35h 
    mov al, 1Ch
    int 21h
 
    mov old_ip_1ch, bx ;сохранение старого прерывания 1ch в переменную
    mov old_cs_1ch, es 
    
    push ds ;сохранение дс в стек 
    mov dx, offset NEW_1CH ;записываем в dх и ах адрес нового прерывания ah
    mov ax, seg NEW_1CH
    mov ds, ax ;сохраняем данные о новом прерывании
    mov ah, 25h ;вызов нового прерывания
    mov al, 1Ch 
    int 21h
    
    pop ds ;возвращаем из стека
    
    mov ax, data
    mov ds, ax
    mov ax, 0B800h ;переход в видеопамять
    mov es, ax
    
    call CLS ;вызов процедуры очистки экрана
    
    mov al,':' ;вывод двоеточия на экран
    mov ah, 10001111b
    mov es:[74*2], ax
    mov es:[77*2], ax

kl: ;основной цикл программы
    cmp exit, 0 ;сравнение для выхода
    jne quit ;если не равно -  выход
    
    cmp clock_out, 0 ;сравнение для вывода времени
    jne kl ;если не меньше то
    call OUT_CLOCK ;вызов процедуры вывода времени
    jmp kl
    
quit:
    call CLS ;опять вызов очистки
 
    mov dx, old_ip_1ch ;возвращаем старое прерывание
    mov ax, old_cs_1ch
    mov ds, ax  ;запуск старого прерывания                                          
    mov ah, 25h                                             
    mov al, 1Ch                                             
    int 21h
    
    mov ax, 4c00h 
    int 21h
code ends
end start
модуль t2.asm
data segment public
data ends
code segment public
assume cs:code, ds:data
public OUT_CLOCK
OUT_CLOCK proc far ;процедура вывода времени
 
    push ax
    push ds
    push es
    
    mov ax, data
    mov ds, ax
    mov ax, 0B800h ;вход в видеопам¤ть
    mov es, ax 

    mov ah, 2h ;вызов системного времени
    int 1Ah 
    
    mov al,ch ;перемещаем в аl часы
    and al,00001111b ;отдел¤ем единицы часов (последние 4 цифры)
    add al,48 ;перевод часов в аски символы
    mov ah, 00001111b ;перемещаем в ah байт атрибутов
    mov es:[73*2], ax ;в 73 ¤чейку перемещаем единицы
    
    mov al,ch ;перемещаем дес¤тки часов
    shr al,4 ;отдел¤ем дес¤тки часов (первые 4 цифры)
    add al,48
    
    mov es:[72*2], ax  ;вывод их
    
    mov al,cl; единицы минут
    and al,00001111b
    add al,48
    dec ah ;мен¤етс¤ цвет
    mov es:[76*2], ax
    
    mov al,cl ;дес¤тки минут
    shr al,4
    add al,48
    
    mov es:[75*2], ax   
    
    mov al,dh ;единицы секунд
    and al,00001111b
    add al,48
    dec ah
    mov es:[79*2], ax
    
    mov al,dh ;дес¤тки секунд
    shr al,4
    add al,48
    
    mov es:[78*2], ax
        
    pop es
    pop ds
    pop ax
    ret ;возвращение обратно
OUT_CLOCK endp
code ends
end
и модуль t3.asm
data segment public
extrn tick: byte
extrn exit: byte 
extrn clock_out: byte
data ends
code segment public
assume cs:code, ds:data
public NEW_1CH
NEW_1CH proc far ;было near новое прерывание 1ch
 
    push ax ; ввод регистров в стек
    push bx
    push cx
    push dx
    push ds
    push es
    
    mov ax, data 
    mov ds, ax
    mov ax, 40h ;вход в буфер клавиатуры
    mov es, ax ;
    mov ax, es:[1ch];в ах адрес хвоста буфера
    mov bx, es:[1ah];в ¬х адрес головы буфера
    cmp bx, ax ;сравнение головы и хвоста
    jne m5 ;если не равно, то переход
    jmp back ; иначе выход из прерывани¤
 
m5: 
    mov al, es:[bx] ; проверка символа в буфере
    mov es:[1ch], bx ; очистка буфера клавиатуры 
    cmp al, 30h ;сверка с кодом клавиши 0 
    jnz ticker ;если не равно то переход
 
    mov exit, 1 ;>>программа выключаетс¤
    jmp back
    
ticker:
    inc tick ;увеличение счетчика тиков таймера
    cmp tick,18 ;сравнение с секундой
    jl back ;если меньше, то выход
    mov tick, 0 ;если больше, то обнул¤етс¤ счетчик
    mov clock_out, 1 ;переход на вывод времени

back:   
    pop es ;возвращение регистров из стека
    pop ds
    pop dx
    pop cx
    pop bx
    pop ax
    iret
NEW_1CH endp ;конец прерывани¤
 
public CLS
CLS proc far ;было near процедура очистки экрана
        push cx
        push ax
        push si
        xor si, si ;обнул¤ем регистр
        mov ah, 7 ;перемещаем цвет в атрибут
        mov al, ''  ;перемещаем пустой символ в ал
        mov cx, 2000 ;перемещаем в цэих количество ¤чеек на экране
CL1:    mov es:[si], ax ;цикл очистки экрана
        inc si
        inc si
        loop CL1
        pop si
        pop ax
        pop cx
        ret
CLS endp
code ends
end

Решение задачи: «Соединение объектных модулей в головной»

textual
Листинг программы
data segment public
 
    public exit, tick, clock_out
 
    exit    db 0  ;переменная выхода
    tick    db 0  ;таймер 1 Сh
    clock_out   db 0  ;переменная таймера
    old_cs_1ch  dw ?  ;старый адрес 1ch
    old_ip_1ch  dw ? 
 
data ends
 
stack segment public
    db 100h dup(?)
stack ends
 
code segment public
assume cs:code, ds:data, ss:stack
 
    extrn   NEW_1CH : far
    extrn   CLS     : far
    extrn   OUT_CLOCK   : far
 
start:  ;НАЧАЛО ОСНОВНОЙ ПРОГРАММЫ
    mov ax, data
    mov ds, ax

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

  1. Объявлены переменные: — exit (db 0) - переменная выхода; — tick (db 0) - таймер 1 Сh; — clock_out (db 0) - переменная таймера; — old_cs_1ch (dw ?) - старый адрес 1ch; — old_ip_1ch (dw ?) - старый адрес 1ch.
  2. Задано начало сегмента данных: mov ax, data.
  3. Переменная ds установлена в значение ax: mov ds, ax. Выше представлен список до 20 элементов, как было указано в задании. Если в коде есть ещё элементы, то их номера и названия переменных не указаны.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

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