Как прыгать между гибкими секторами в сборке? - использовать NASM вызовом далеко и ретф? - PullRequest
1 голос
/ 21 ноября 2011

Я новичок в программировании в asm. Я пытаюсь создать дискету, которая печатает сообщение в загрузочном секторе, переходит в сектор 35 и печатает дату, затем переходит обратно в загрузочный сектор и печатает приглашение. У меня возникают проблемы (я думаю), когда я переключаюсь между секторами ... У меня все печаталось нормально, когда все было в загрузочном секторе, и я не изменил фактический код печати. В настоящее время я получаю первую строку сообщения, а затем дату и приглашение никогда не печатать. Код ниже; Я использую NASM:

Для загрузочного сектора:

org 0x7c00 ;load to appropariate MBR location

start:
  call cls  ;call routine to clear screen
  call dspmsg   ;call routine to display message

  mov ah,02h ;read disk sectors into memory
  mov al,1 ;number of sectors to read/write (must be nonzero)
  mov ch,1 ;cylinder number (0...79)
  mov cl,18 ;sector number (1...18)
  mov dh,0 ;head number (0...1)
  mov dl,0 ;drive number (0...3, 0 for floppy)
  mov bx, 0x1000
  mov es,bx
  mov bx,0x0000
  int 13h

  call word 0x1000:0x0000

  push cs
  pop ds

  call dspmsg2

  jmp $

%macro dsp 3
mov ah,13h ;function 13h (Display String)
mov al,1 ;Write mode is one
mov bh,0 ;Use video page of zero
mov bl,0AH ;Attribute
mov cx,%1 ;Character string length
mov dh,%2 ;position on row
mov dl,0 ;and column 28
push ds ;put ds register on stack
pop es ;pop it into es register
lea bp,%3 ;load the offset address of string into BP
int 10H
%endmacro

cls:             
  mov ah,06h    ;function 06h (Scroll Screen)
  mov al,0  ;scroll all lines
  mov bh,0AH    ;Attribute (light green on black)
  mov ch,0  ;Upper left row is zero
  mov cl,0  ;Upper left column is zero
  mov dh,24 ;Lower left row is 24
  mov dl,79 ;Lower left column is 79
  int 10H   ;BIOS Interrupt 10h (video services)
  ret

msg: db 'OS321, made by CHRISTINE MCGINN (c) 2011'

dspmsg: 
  dsp 40,0,[msg]
  ret

msg2: db '$'

dspmsg2:
;Display a message
dsp 1,2,[msg2]
ret

times 510-($-$$) db 0   ;Pad remainder of boot sector with 0s
dw 0xAA55 ;done setting the MBR

Затем в секторе 35:

org 0x0000

push cs
pop ds 

  call date
  call cvtmo
  call cvtday
  call cvtcent
  call cvtyear

  call time
  call cvthrs
  call cvtmin
  call cvtsec
  call dsptimedate

  retf

%macro dsp 3
mov ah,13h ;function 13h (Display String)
mov al,1 ;Write mode is one
mov bh,0 ;Use video page of zero
mov bl,0AH ;Attribute
mov cx,%1 ;Character string length
mov dh,%2 ;position on row
mov dl,0 ;and column 28
push ds ;put ds register on stack
pop es ;pop it into es register
lea bp,%3 ;load the offset address of string into BP
int 10H
%endmacro

%macro cvt 3
mov bh,%1 ;copy contents of %1 to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmdtfld + %2],bh
mov bh,%1
and bh,0fh
add bh,30h
mov [tmdtfld + %3],bh
%endmacro

date:
;Get date from the system
mov ah,04h   ;function 04h (get RTC date)
int 1Ah     ;BIOS Interrupt 1Ah (Read Real Time Clock)
ret

;CH - Century
;CL - Year
;DH - Month
;DL - Day

cvtmo:
;Converts the system date from BCD to ASCII
cvt dh,9,10
ret

cvtday:
cvt dl,12,13
ret

cvtcent:
cvt ch,15,16
ret

cvtyear:
cvt cl,17,18
ret

time:
;Get time from the system
mov ah,02h
int 1Ah
ret

;CH - Hours
;CL - Minutes
;DH - Seconds

cvthrs:
;Converts the system time from BCD to ASCII
cvt ch,0,1
ret

cvtmin:
cvt cl,3,4
ret

cvtsec:
cvt dh,6,7
ret

tmdtfld: db '00:00:00 00/00/0000'

dsptimedate:
;Display the system time
dsp 19,1,[tmdtfld]
ret

times 512-($-$$) db 0   ;Pad remainder of sector with 0s

Спасибо за любую помощь, которую вы можете предложить!

1 Ответ

1 голос
/ 22 ноября 2011

Вы поставили вопрос в замешательстве. Кажется, у вас есть две проблемы:

1) Чтение произвольных секторов с дискеты

2) Наличие программ в каждом секторе, которые что-то делают (например, печатают строку)

Я бы организовал свою программу как драйвер для дискет ("call floppy_read_sector (x)") [который мог бы использовать биос, чтобы сделать большую часть грязной работы, но это детали реализации), и как набор отдельных позиционно-независимых блоков кода, которые выполняли различные задачи как подпрограммы.

Ваш код загрузочного сектора должен содержать драйвер дискеты и логику высокого уровня чтобы прочитать сектор (n), вызовите подпрограмму в буфере, в который вы читаете сектор, а затем сделать следующий сектор. (У вас не так много места, поэтому я не знаю, если вы можете втиснуть все это в загрузочный сектор. Добро пожаловать на язык ассемблера программирование, где важен подсчет байтов).

Тогда вам нужно как-то организовать конструкцию дискеты. Обычно в мире, где создаются загрузочные дискеты, вам разрешено создавать гораздо более сложные программы, чтобы заполнить их. Упражнение, оставленное читателю.

...