我可以使用bios int 13h的扩展读取功能,
使用以下代码
; *************************************************************************
; Setup DISK ADDRESS PACKET
; *************************************************************************
jmp strtRead
DAPACK :
db 010h ; Packet Size
db 0 ; Always 0
blkcnt:
dw 1 ; Sectors Count
db_add :
dw 07e00h ; Transfer Offset
dw 0 ; Transfer Segment
d_lba :
dd 1 ; Starting LBA(0 - n)
dd 0 ; Bios 48 bit LBA
; *************************************************************************
; Start Reading Sectors using INT13 Func 42
; *************************************************************************
strtRead:
mov si, OFFSET DAPACK; Load DPACK offset to SI
mov ah, 042h ; Function 42h
mov dl, 080h ; Drive ID
int 013h; Call INT13h
我想把它转换成一个c可调用函数,但我不知道如何将参数从c转换成asm,比如驱动器id、扇区计数、缓冲区段:偏移量。。。。等。
我正在使用msvc和masm,除了bios功能外什么都不做。
有人能帮忙吗?!!
更新:
我试过下面的函数,但总是没有加载到缓冲区中??
void read_sector()
{
static unsigned char currentMBR[512] = { 0 };
struct disk_packet //needed for int13 42h
{
byte size_pack; //size of packet must be 16 or 16+
byte reserved1; //reserved
byte no_of_blocks; //nof blocks for transfer
byte reserved2; //reserved
word offset; //offset address
word segment; //segment address
dword lba1;
dword lba2;
} disk_pack;
disk_pack.size_pack = 16; //set size to 16
disk_pack.no_of_blocks = 1; //1 block ie read one sector
disk_pack.reserved1 = 0; //reserved word
disk_pack.reserved2 = 0; //reserved word
disk_pack.segment = 0; //segment of buffer
disk_pack.offset = (word)¤tMBR[0]; //offset of buffer
disk_pack.lba1 = 0; //lba first 32 bits
disk_pack.lba2 = 0; //last 32 bit address
_asm
{
mov dl, 080h;
mov[disk_pack.segment], ds;
mov si, disk_pack;
mov ah, 42h;
int 13h
; jc NoError; //No error, ignore error code
; mov bError, ah; // Error, get the error code
NoError:
}
}
最佳答案
很抱歉以“回答”的形式发布;我想以“评论”的形式发布,但是太长了。。。
不同的编译器具有不同的内联程序集语法。这意味着以下行的正确语法:
mov[disk_pack.segment], ds;
mov si, disk_pack;
…取决于使用的编译器。不幸的是,我没有使用16位C编译器,所以在这一点上我帮不了你。
我在你的程序中看到的下一件事是:
disk_pack.segment = 0; //segment of buffer
disk_pack.offset = (word)¤tMBR[0]; //offset of buffer
有99%的可能性这会导致问题。相反,我想说:
struct disk_packet //needed for int13 42h
{
byte size_pack;
byte reserved;
word no_of_blocks; // note that this is 16-bit!
void far *data; // <- This line is the main change!
dword lba1;
dword lba2;
} disk_pack;
...
disk_pack.size_pack = 16;
disk_pack.no_of_blocks = 1;
disk_pack.reserved = 0;
disk_pack.data = ¤tMBR[0]; // also note the change here
disk_pack.lba1 = 0;
disk_pack.lba2 = 0;
...
请注意,有些编译器将关键字“far”或“far”命名为“far”。
第三个问题是,有些(错误的)bios要求ES等于磁盘包中的段值,第四个问题是,许多编译器要求内联汇编代码不修改任何寄存器(AX、CX和DX通常都可以)。
这两个问题可以通过以下方式解决:
push ds;
push es;
push si;
mov dl, 080h;
// TODO here: Set ds:si to disk_pack in a compiler-specific way
mov es,[si+6];
mov ah, 42h;
int 13h;
...
pop si;
pop es;
pop ds;
我认为“#pragma pack”不应该是必需的,因为结构中的所有元素都是适当对齐的。
关于c - INT 13扩展读入C,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32309719/