140 likes | 280 Views
SP 程式報告. 91156227 林哲立. 題目說明. 使用磁區展示程式,使用者輸入數字,作為磁區開頭號碼,以及所要顯示的磁碟號碼,輸出為所顯示的內容 (in hexadeximal) 此題目可以在 Windows95.98 及 ME 底下被執行,但是無法在 Windows NT.2000 及 XP 底下執行,原因是它們有較高的磁碟安全存取權限制. 流程說明. AskForSectorNumber. ReadSector. CannotRead. OK. DisPlaySector. ESC to Leave. ReadChar. Next Sector.
E N D
SP程式報告 91156227 林哲立
題目說明 • 使用磁區展示程式,使用者輸入數字,作為磁區開頭號碼,以及所要顯示的磁碟號碼,輸出為所顯示的內容(in hexadeximal) • 此題目可以在Windows95.98及ME底下被執行,但是無法在Windows NT.2000及XP底下執行,原因是它們有較高的磁碟安全存取權限制
流程說明 AskForSectorNumber ReadSector CannotRead OK DisPlaySector ESC to Leave ReadChar Next Sector
範例及概念說明 • INT21h,函數7305h可用來讀寫邏輯磁碟的磁區,和所有的INT指令相同,它被設計只能在16位元實體位址模式下執行,當呼叫7305h函數時需要傳入下列參數: • AX:7305h • DS/BX:一個磁碟I/O結構變數位址的區段/偏移值(segment/offset) • CX:0FFFFh • DL:磁碟機編號(0=預設,1=A,2=B…) • SI:讀/寫旗標(讀取=0)
EX:讀取一個磁區 • Mov ax,7305h Mov cx,0FFFFh Mov dl,3 ;磁碟C Mov bx,offset diskstruct ;DiskIO結構 Mov si,0 ;讀取 Int 21h
Setcursor PROTO,row:byte,col:byte • EOLN EQU <0dh,0ah> ;換行動作 • esc_key = 1Bh ;27為離開動作 • data_row=7 • data_col=0 • sector_size=512 • read_mode=0 ;函數7305h設定用 • DiskIO STRUCT • startSector dword ? ;起始磁區編號 • numSectors word 1 ;想要讀取的磁區數 • bufferOfs word buffer ;緩衝區偏移值 • bufferSeg word @DATA ;緩衝區區段 • DiskIO ENDS
drivenumber byte ? • drivename byte ?,":\",EOLN,EOLN,0;output • diskStruct DiskIO <> • buffer byte sector_size dup(0),0 ;一個磁區 • curr_row byte ? • curr_col byte ?;字串資源 • strline byte EOLN,79 dup(0c4h),EOLN,0 • strheading byte "sector display program(sector32.exe)" • byte EOLN,EOLN,0 • strasksector byte "enter starting sector number:",0 • straskdrive byte "enter drive number(1=A,2=B " • byte "3=C,4=D,5=E,6=F):",0 • strcannotread byte EOLN,"*** cannot read the sector." • byte "press any key...",EOLN,0 • strreadingsector \ • byte "press esc to quit" • byte EOLN,EOLN,"reading sector: ",0
Call Askforsectornumber • L1:call clrscr • call readsector ;讀取磁區 • jc L2 ;發生錯誤時離開(進位) • call displaysector • call readchar • cmp al,ESC_KEY ;是否按下ESC • je L3 ;yes,離開 • inc diskstruct.startsector ;下一個磁區 • jmp L1 ;重複迴圈 • L2:mov dx,offset strcannotread ;error message • call writestring • call readchar • L3:call Clrscr • exit
Askforsectornumber PROC • pusha • mov dx,offset strasksector • call writestring • call readint • mov diskstruct.startsector,eax • call crlf • mov dx,offset straskdrive • call writestring • call readint • mov drivenumber,al • mov si,offset drivename ;set drivename from drivenumber • add al,40h ;1=drive A (41h) • mov [si],al • call crlf • popa • ret • Askforsectornumber endp
Readsector PROC • pusha • mov ax,7305h ;absdiskreadwrite • mov cx,-1 ;定值-1 • mov dl,drivenumber ;磁碟代碼(槽代號) • mov bx,offset diskstruct ;磁區編號 • mov si,read_mode ;讀取模式(讀取) • int 21h ;讀取磁碟磁區 • popa • ret • readsector endp
Displaysector PROC • mov dx,offset strheading ;顯示 heading • call writestring • mov dx,offset drivename • call writestring • mov eax,diskstruct.startsector ;顯示磁區編號 • call writehex • mov dx,offset strline ;水平線 • call writestring • mov si,offset buffer ;指向 buffer • mov curr_row,data_row ;設定列,行(7,0) • mov curr_col,data_col • invoke setcursor,curr_row,curr_col;磁區位置
mov cx,sector_size • mov bh,0 ;視訊頁 0 • L1: push cx ;儲存迴圈計數 • mov ah,0Ah ;顯示字元 • mov al,[si] ;由buffer讀取位元 • mov cx,1 ;顯示出來 • int 10h • call movecursor • inc si ;指向下一個位元 • pop cx ;復原迴圈計數 • loop L1 ;重複迴圈計數 • ret • Displaysector endp
Movecursor PROC • cmp curr_col,79 ;最後一行? • jae L1 ;是;到下一列 • inc curr_col ;否;增加行 • jmp L2 • L1:mov curr_col,0 ;下一列 • inc curr_row • L2:invoke setcursor,curr_row,curr_col • ret • movecursor endp
Setcursor PROC uses dx,row:byte,col:byte • ;set the screen cursor position • mov dh,row • mov dl,col • call gotoxy • ret • setcursor endp