бегущая строка под Dos

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

Ответить
fron
Сообщения: 3
Зарегистрирован: 04 июн 2007, 11:37

04 июн 2007, 11:45

помогите плз с задачкой:
Составить программу для ввода с клавиатуры строки символов. Записать строку в буфер buf и организовать вывод бегущей строки.
Прога должна работать под управлением MS DOS.
Инструментальная среда TASM 5.10 (MASM 6.11).

спс.
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

04 июн 2007, 14:26

Код: Выделить всё

.model small
.386
.stack
.code
jmp @start

buf db 255, 0, 255 dup (0)
s_inputstring db 'Input string : $'
s_keypress    db 0Dh, 0Ah, 'Press any key to exit$'
log_position  dw 0
max_position  dw 0
out_position  dw 12

; ===================== Waiting timer
WaitTimer proc near
push es
push ax
xor ax, ax
mov es, ax
mov ax, es:[46Ch]
	@waiting:
cmp ax, es:[46Ch]
jz @waiting
pop ax
pop es
ret
WaitTimer endp

; ===================== Running string output
OutRunString proc near
pusha
push es
cld
mov ax, 0B800h
mov es, ax
mov ax, Out_Position
imul ax, ax, 160         ; Calculating offset
mov di, ax
mov si, ax
mov cx, 80
mov ax, 03420h
rep stosw                ; Filling whole line by spaces
mov cx, 80               ; Characters to end of line
mov di, si
mov si, offset Buf + 2   ; First char of string
movzx bp, [si-1]
add bp, si               ; Last char of string + 1
mov ax, Log_Position
cmp ax, cx
jnc @no_offset           ; If position >= 80 then no need to offset string

sub cx, ax
add di, cx
add di, cx
mov cx, ax               ; Calc offset and length
jmp short @outstr
	@no_offset:
sub ax, cx
add si, ax               ; Calc first output character
	@outstr:
jcxz @outend
mov ah, 034h
mov al, [si]
stosw                    ; Out character
inc si
cmp si, bp               ; If end of line or end of string then exit
jz @outend
dec cx
jmp short @outstr
	@outend:
pop es
popa
retn
OutRunString endp

; ========================= MAIN CODE ================================
	@start:
push cs
pop ds
mov ax, 3                        ; Videomode 80x25
int 10h
mov dx, offset s_inputstring
mov ah, 9
int 21h
mov ah, 0Ah
mov dx, offset buf
int 21h                          ; Buffered input
mov dx, offset s_keypress
mov ah, 9
int 21h
movzx ax, byte ptr buf + 1
add ax, 80
mov Max_Position, ax
	@work:
call WaitTimer                   ; Waiting 1/18 sec.
inc Log_Position
mov ax, Log_Position
cmp ax, Max_Position             ; If LogPos > MaxPos then LogPos = 0
jnz @skip
mov Log_Position, 0
	@skip:
call OutRunString                ; Out running string
mov ah, 0Bh
int 21h
or al, al                        ; If not key pressed, then continue
jz @work

mov ah, 0Ch
int 21h                          ; Flush key buffer

mov ax, 4C00h
int 21h

end
Это один из способов. Алгоритм использует больше вычислительных операций, зато не использует дополнительной памяти.
It's a long way to the top if you wanna rock'n'roll
fron
Сообщения: 3
Зарегистрирован: 04 июн 2007, 11:37

04 июн 2007, 15:45

Огромное спасибо! Очень выручил :)

ток возникает при линке ошибка:
Fatal: No program entry point
((
Не подскажешь почему?
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

04 июн 2007, 15:50

Это зависит от компилятора, по идее Entry Point в этой программе по умолчанию 0000:0000 - но более старшие версии могут поругаться, что она не задана - в любом случае фатальной ошибки быть не должно
It's a long way to the top if you wanna rock'n'roll
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

04 июн 2007, 17:31

Может, делу поможет замена самого последнего end на:
end @start
или
end start

Я в своих программках именно так писал. Правла, у меня метки отчего-то всегда были без "собачек" первым символом, т.примерно так:

Код: Выделить всё

  .model tiny
  .code

  ORG 100h

start:

 ;; Do something here ...   

end start
fron
Сообщения: 3
Зарегистрирован: 04 июн 2007, 11:37

05 июн 2007, 03:14

Еще раз огромное спасибо!!))
Помогло) просто в конце исправил на end @start
Очень вам признателен.
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

05 июн 2007, 10:07

fron писал(а):Еще раз огромное спасибо!!))
Помогло) просто в конце исправил на end @start
Очень вам признателен.
Посмотел чуть повнимательнее на свои тексты и на текст, выложенный somewhere. У него первым оператором (после строки .code)стоит jmp @start.
У меня всегда структура исх.текста была следующая:

Код: Выделить всё

.model tiny
  .code

  ORG 100h

start:
     jmp  begin

  ;; Здесь размещались различные процедуры и данные

begin:
  ;; Здесь начиналась собственно программа

end start
То есть, я хоче сказать, что не знаю (не помню), корректно ли указывать начальную точку программы (т.е. то, что пишется в последнем end) "посредине" исходного текста. Возможно, лучше указывать "самую верхнюю" точку. Т.е. начало кода somewhere изменить на:

Код: Выделить всё

.model small
.386
.stack
.code
  @start_point:
jmp @start
А последней строкой тогда будет:

Код: Выделить всё

end @start_point
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

05 июн 2007, 10:27

&quot писал(а):Правла, у меня метки отчего-то всегда были без "собачек" первым символом
Это просто я так метки обозначаю, всегда начиная с "собачки"
По сути, ошибок нет, т.к. стоит директива .CODE - которая и обозначает Entry Point
Не знаю как там в MASM, но в TASM нет никаких вопросов
Вот типичный пример из книжки по TASM

Код: Выделить всё

   .MODEL SMALL
   .STACK 100h
   .DATA
Message  DB 'Привет!',13,10,'$'
   .CODE
   mov    ax,@Data
   mov    dx,ax                   ; установить регистр DS таким
                                  ; образом, чтобы он указывал
                                  ; на сегмент данных
   mov    ah,9                    ; функция DOS вывода строки
   mov    dx,OFFSET Message       ; ссылка на сообщение "Привет!"
   int    21h                     ; вывести "Привет!" на экран
   mov    ah,4ch                  ; функция DOS завершения
                                  ; программы
   int    21h                     ; завершить программу
   END 
P.S. - оказывается даже здесь ошибки бывают, для тех кто не заметил - в самом начале
It's a long way to the top if you wanna rock'n'roll
Ответить