雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。
1: 2005-07-24 (日) 17:04:52 ソース バックアップ No.1 を復元して編集
Line 1: Line 1:
 + ==================================================
 + [BITS 16]
 + [OPTIMIZE 1]
 + [OPTION 1]
 + [INSTRSET "8086"]
 + [FORMAT "BIN"]
 + ORG 0x100
 + ;----------------------------------------------
 + ;-----------初期値。AXに開始セクタ値、DXに終了セクタ値
 +
 +  MOV AX,33
 +  MOV DX,161
 +
 + ;--繰り返す回数を求めておく。
 +  SUB DX,AX ;DXの値は破壊されるが、回数が得られれば
 +  ;いらないはず。
 +
 +  MOV CX,DX ;CXに回数がセットされた。
 +
 +
 + ;--ヘッドの値を求める---
 +  PUSH    CX ;CXには回数が入っている。バックアップ
 +  PUSH    AX ;AXには論理セクタ値が入っている。一旦バックアップ。
 +
 +  MOV    CX,2880 ;まず、CXに総セクタ数を入れる。
 +  SHR    CX,1 ;CX ÷ 2 を実行ししたのと同じ結果になる。
 +
 +  MOV    DX,0 ;これでDX:AXの値は32bitながら論理セクタ値となるはず。
 +
 +  DIV    CX ;これで、AXにはhの値が入っているはず。
 +
 +  MOV    DX,AX ;AXの値(h)をDXレジスタに移す
 +
 +  POP AX ;AXを初期値に戻す(論理セクター値)
 +  POP    CX ;CXを初期値に戻す
 +
 + ;--この時点で、AXに開始値、CXに回数、DXにはヘッド値が入るはず。
 +
 +  MOV DH,DL ;DHにヘッド値を移す
 +  MOV DL,0 ;DLにドライブ番号をあてる
 +
 + ;--これで、DXレジスタの値は完成したはず。
 +
 +
 +
 + ;--シリンダ値を求める
 + ;シリンダ値の算出にヘッダ値がいるので先に行う
 + ;------ Q = B ÷ A ÷ 2   ;先に一面のシリンダ数を求める
 + ;------ c = R ÷ A - (Q * h)
 +
 +  PUSH DX ;例によってレジスタをバックアップ
 +  PUSH CX
 +  PUSH AX
 +  ;---以下のスタック位置を、仮称でV地点とする
 +  PUSH AX ;AXの値が計算で必要なのでもう一回保存
 +
 +  MOV AX,2880 ;AXに総セクタ数をセット(B)
 +  ;--DHにはヘッド値が入っているのでDLを使う
 +  MOV DL,18 ;DLにシリンダ内のセクタ数をセット(A)
 +  SHR DL,1 ;A÷2が完成する
 +  DIV DL ;(Q)がALにセットされた
 +
 +  ;--この時点ではとりあえずAXの値はもう壊れてもかまわない
 +  MOV AL,DH ;ヘッド値をALに移す
 +  MUL DL ;AL × DL(Q*h)が実行され、答えはAXに入る。
 +
 +  ;上記でAXに得られた値とV地点とを入れ替える作業。
 +  ;(おかしな処理だが、ようは置く所がないため)
 +
 +  MOV DX,AX ;AXの値をDXに複製
 +  POP AX ;V地点の値がAXに戻ってくる
 +  PUSH DX ;得られた(Q*h)がV地点にバックアップされる
 +
 +  ;上記の処理で入れ替えと、AXにRを入れる処理が完成する
 +  ;また、DXの値(Q*h)はバックアップされたので壊れてもよい。
 +
 +  MOV DL,18 ;DLに18(A)をセットする。
 +  DIV DL ;AX ÷ DL が実行され、ALに答えが入る
 +  MOV AH,0 ;これでALの値をムリヤリ16ビット化する。
 +  ;次の引き算のため符号をそろえる
 +
 +  POP DX ;v地点の値(Q*h)をDXにレストアする。
 +
 +  SUB AX,DX ;最終的な答えが得られるが、マイナスになる
 +  ;場合もある。しかし、この値は8ビットなので、
 +  ;上位8ビットを切り捨てればOK。つまり、ALの
 +  ;値がシリンダ値。
 +
 +  MOV BX,AX ;置く所がないのでBXに転送
 +
 +  POP AX ;レジスタをレストア
 +  POP CX
 +  POP DX
 +
 +  ;この時点で、AXに論理セクタ値、CXに回数、DXにドライブ番頭&ヘッド値、
 +  ;BXにシリンダ値が入っていることになる。
 +
 +
 +
 + ;--セクタ値を求める
 + ;-----------s = R mod A + 1
 +  PUSH DX ;レジスタのバックアップ
 +  PUSH CX
 +  PUSH AX
 +  PUSH BX
 +
 +
 +  MOV DL,18 ;DLレジスタに物理セクタ数をセット
 +
 +  DIV DL ;AX÷DLが実行され、AHに余りが入る
 +
 +  ADD AH,1 ;AHにセクタ値が得られたはず。
 +
 +  POP BX ;BXをレストア。BLにはシリンダ値がある。
 +
 +  ;BIOSを呼ぶ時の値と逆なのでひっくり返す。
 +
 +  MOV BH,BL ;BLにあるシリンダ値をBHに移す
 +  MOV BL,AH ;AHのセクタ値をBLに移す。
 +
 +  ;これによって、BHにシリンダ値、BLにセクタ値が得られる。
 +  ;あとはこのBXの値をCXに移せばOKとなる。
 +
 +  POP AX ;レジスタのレストア
 +  POP CX
 +  POP DX
 +
 + ;ーーこの時点で、AXに開始値、CXに回数、DXにドライブ&ヘッド値、BXにシリンダ&セクタがセットされているはず。
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +
 +;--end---
 +
 +;----------------------------------------------
 +MOV AX,0x4c00
 +INT 0x21
 +===============================================