我可以使用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)&currentMBR[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)&currentMBR[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 = &currentMBR[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/

10-11 16:40