Intel(R) Core(TM)2 Duo T8100 @2.10GHz 2.10GHz
RAM 4.00GB
gcc 4.7.2
自作開発補助ツール(このトピックと共通)
フロッピーディスクのブートセクタで実行し、同ディスクのルートにあるBOOT.BINを読み込んで実行するプログラムを書いたのですが、
試した中でVMware Playerでだけうまく動かなくて困っています。
添付ファイルの中にあるvmwtest.imgをフロッピーディスクとして読み込み、
VirtualBox 4.2.18、QEMU 0.13.0、VMware Player 6.0.0で起動しました。
仮想マシンのRAMは全て256MBに設定しています。
VirtualBoxとQEMUではきちんとHello, World!と表示されたのですが、
VMware Playerでは「err0(改行)0」と表示され、うまく実行できませんでした。
ブートローダーのプログラムはこれです。(添付loader.s)
► スポイラーを表示
.code16gcc
.macro call operand
callw \operand
.endm
.macro ret
retw
.endm
.org 0x7C00
.global _start
_start:
jmp _main
nop
.ascii "ASMPRGRM"
.word 0x0200 # BytesPerSector
.byte 0x01 # SectorPerCluster
.word 0x0001 # ReservedSectors
.byte 0x02 # TotalFATs
.word 0x00E0 # MaxRootExtries
.word 0x0B40 # TotalSectors
.byte 0xF0 # MediaDescriptor
.word 0x0009 # SectorsPerFAT
.word 0x0012 # SectorsPerTrack
.word 0x0002 # NumHeads
.long 0x00000000 # HikkenSector
.long 0x00000000 # TotalSectors
.byte 0x00 # DriveNumber
.byte 0x00 # Reserved
.byte 0x29 # BootSignature
.long 0x12345678 # VolumeSerialnumber
.ascii "LOADER " # VolumeLabel
.ascii "FAT12 " # FileSystemType
TXT_BOOTBIN:
.ascii "BOOT BIN\0"
_main:
cli
mov $0xFFF0,%sp
xor %ah,%ah
xor %dl,%dl
int $0x13
jc errorexit
# read FAT to 0x9000:0x0000
mov $0x9000,%bx
mov %bx,%es
mov $0x01,%bx
call fposcalc
mov $0x0209,%ax
xor %bx,%bx
int $0x13
jc errorexit
# read root to 0x9000:0x1200
mov $0x13,%bx
call fposcalc
mov $0x020E,%ax
mov $0x1200,%bx
int $0x13
jc errorexit
xor %dx,%dx
mov %dx,%es
lea TXT_BOOTBIN,%dx
call searchfile
test %ax,%ax
jz errorexit
mov %cx,%dx
mov %bx,%cx
mov $0x0500,%bx
call getfiledata
xor %ax,%ax
mov %ax,%si
mov %ax,%di
mov %ax,%bp
mov %ax,%es
mov $outputnumber,%bx
mov $searchfile,%cx
mov $getfiledata,%dx
pushw $0x0500
ret
errorexit:
mov %ah,%dl
mov $0x0E65,%ax
mov $0x0007,%bx
int $0x10
mov $0x72,%al
int $0x10
int $0x10
xor %ch,%ch
mov %dl,%cl
call outputnumber
mov $0x0E0D,%ax
mov $0x0007,%bx
int $0x10
mov $0x0A,%al
int $0x10
hlt
#put number to output on %cx then call this
outputnumber:
push %ax
push %cx
push %dx
push %bx
pushw $10
MAKEOUTPUTLOOP:
mov %cx,%ax
xor %dx,%dx
mov $10,%bx
div %bx
push %dx
mov %ax,%cx
test %cx,%cx
jnz MAKEOUTPUTLOOP
mov $0x0E,%ah
mov $0x0007,%bx
OUTPUTLOOP:
pop %cx
cmp $10,%cx
je OWARIDAYO
mov %cl,%al
add $48,%al
int $0x10
jmp OUTPUTLOOP
OWARIDAYO:
pop %bx
pop %dx
pop %cx
pop %ax
ret
# put sector ID(0-origin) to %bx, then call
# after return, set operation and address, then do int $0x13
fposcalc:
push %si
push %di
push %ax
mov %bx,%ax
xor %dx,%dx
mov $18,%cx
div %cx
inc %dx
and $1,%ax
shl $8,%ax
mov %ax,%si
mov %dx,%di
mov %bx,%ax
xor %dx,%dx
mov $36,%cx
div %cx
mov %al,%ch
mov %ah,%cl
shl $6,%cl
mov %di,%dx
or %dl,%cl
mov %si,%dx
pop %ax
pop %di
pop %si
ret
# search specified file from root
# input %dx : address of file name to search
# return %ax : first sector of the file (0 if not found)
# return %bx : file size (lower 16-bits) (undefined if not found)
# return %cx : file size (higher 16-bits) (undefined if not found)
searchfile:
push %si
push %di
push %es
mov $0x9000,%cx
mov %cx,%es
mov $0xE0,%cx
mov $0x1200,%bx
SEARCHLOOP:
testb $0x08,%es:0xB(%bx)
jnz SEARCHSKIP
mov %dx,%si
mov %bx,%di
call filematch
jz SEARCHFOUND
SEARCHSKIP:
add $0x20,%bx
loop SEARCHLOOP
xor %ax,%ax
jmp SEARCHEXIT
SEARCHFOUND:
mov %es:0x1A(%bx),%ax
mov %es:0x1E(%bx),%cx
mov %es:0x1C(%bx),%bx
SEARCHEXIT:
pop %es
pop %di
pop %si
ret
# compare file name
# input %si : file name to search
# input %di : file name on disk (will accessed with "%es:")
# output : ZF=1 if same, ZF=0 if differ
# breaks %si,%di
filematch:
push %cx
push %ax
mov $11,%cx
dec %si
dec %di
COMPLOOP:
inc %si
inc %di
mov (%si),%al
cmp %es:(%di),%al
jnz COMPEXIT
loop COMPLOOP
COMPEXIT:
pop %ax
pop %cx
ret
# get data from FAT
# input %dx : the index to get data
# output %ax : cluster ID on the index
getfatdata:
push %si
push %di
push %es
mov $0x9000,%si
mov %si,%es
mov %dx,%si
shr $1,%si
mov %si,%di
add %di,%si
add %di,%si
test $1,%dl
jz GETFATEVEN
mov %es:1(%si),%ax
shr $4,%ax
jmp GOTFATODD
GETFATEVEN:
mov %es:(%si),%ax
and $0xF,%ah
GOTFATODD:
pop %es
pop %di
pop %si
ret
/*
# get file data from disk
# input %ax : the first sector to read
# input %bx : address to read data
# input %cx : size to read (note: size written will be rounded up to a multiple of 0x200)
getfiledata:
test %cx,%cx
jz NODATATOREAD
push %ax
push %cx
push %dx
push %bx
mov %ax,%dx
GETFILELOOP:
mov %dx,%ax
add $31,%ax # "2" on fat is sector 0x21 (0-origin)
push %cx
push %dx
push %bx
mov %ax,%bx
call fposcalc
mov $0x0201,%ax
pop %bx
int $0x13
jc errorexit
pop %dx
pop %cx
call getfatdata
mov %ax,%dx
add $0x200,%bx
sub $0x200,%cx
ja GETFILELOOP
pop %bx
pop %dx
pop %cx
pop %ax
NODATATOREAD:
ret
*/
# get file data from disk
# input %ax : the first sector to read
# input %es:%bx : address to read data (note: if %bx is not a multiple of 0x200, it may be broken)
# input %cx : size to read (note: size written will be rounded up to a multiple of 0x200)
# input %dx : size to read (higher 16 bits)
getfiledata:
test %cx,%cx
jnz NO_NODATATOREAD
test %dx,%dx
jz NODATATOREAD
NO_NODATATOREAD:
push %ax
push %cx
push %dx
push %bx
push %si
push %es
mov %dx,%si
mov %ax,%dx
GETFILELOOP:
mov %dx,%ax
add $31,%ax # "2" on fat is sector 0x21 (0-origin)
push %cx
push %dx
push %bx
mov %ax,%bx
call fposcalc
mov $0x0201,%ax
pop %bx
int $0x13
jc errorexit
pop %dx
pop %cx
call getfatdata
mov %ax,%dx
add $0x200,%bx
jnc ADDR_NOCARRY
mov %es,%ax
add $0x1000,%ax
mov %ax,%es
ADDR_NOCARRY:
sub $0x200,%cx
ja GETFILELOOP
test %si,%si
jz DATAREADEND
dec %si
jmp GETFILELOOP
DATAREADEND:
pop %es
pop %si
pop %bx
pop %dx
pop %cx
pop %ax
NODATATOREAD:
ret
► スポイラーを表示
.code16gcc
.global _start
_start:
mov $0x0e,%ah
xor %bx,%bx
mov $0x48,%al
int $0x10
mov $0x65,%al
int $0x10
mov $0x6C,%al
int $0x10
# mov $0x6C,%al
int $0x10
mov $0x6F,%al
int $0x10
mov $0x2C,%al
int $0x10
mov $0x20,%al
int $0x10
mov $0x57,%al
int $0x10
mov $0x6F,%al
int $0x10
mov $0x72,%al
int $0x10
mov $0x6C,%al
int $0x10
mov $0x64,%al
int $0x10
mov $0x21,%al
int $0x10
hlt
メモリ破壊やサブルーチンの呼び出し前後で%spの値がずれるなどのバグがあるかもしれません。
しかし、ソースコードを読み返しても発見できませんでした。
もし原因が分かりましたら、教えていただければありがたいです。
よろしくお願いします。
【追記】
Bochs 2.6.2でもHello, World!と表示されました。
【さらに追記】
http://www.geocities.co.jp/SiliconValle ... toiso.html
のツールでisoファイルに変換し、QEMUで動作確認したあと実機(FMV-BIBLO NF/B50)でテストしましたが、
「err0(改行)0」が大量に出力されました。これはVMware Playerでisoイメージを使った時と同じ挙動(もちろん失敗)です。