【问题标题】:How to jump between floppy sectors in assembly? - use of NASM call far and retf?如何在装配中的软盘扇区之间跳转? - 使用 NASM 调用 far 和 retf?
【发布时间】:2012-03-31 09:55:03
【问题描述】:

我是 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

感谢您提供的任何帮助!

【问题讨论】:

  • 我卡在同一个地方。我想软盘读取失败,由于错误的扇区或磁头。我用虚拟机测试过,但不知道虚拟软驱有多少个磁头,也不知道它的其他属性..:D

标签: pointers assembly nasm


【解决方案1】:

您以一种令人困惑的方式提出问题。你似乎有两个问题:

1) 从软盘读取任意扇区

2) 在每个扇区中都有执行某些操作的程序(例如,打印字符串)

我会将我的程序组织为软盘驱动程序(“call floppy_read_sector(x)”)[这可能 使用 bios 来完成大部分脏活,但这是一个实现细节), 以及作为完成各种任务的独立位置无关代码块的集合 作为子程序。

您的引导扇区代码应包含软盘驱动程序和高级逻辑 要读取扇区(n),请调用您读取扇区的缓冲区中的子例程, 然后做下一个扇区。 (你没有很多空间所以我不知道 如果您可以将所有这些都压缩到引导扇区中。欢迎使用汇编语言 计算字节数很重要的编程)。

然后你必须以某种方式组织软盘的构建。 通常在创建可引导软盘的世界中,您可以构建 更复杂的程序来填充它们。练习留给读者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多