INT 13扩展读入C

时间:2015-08-31 11:01:21

标签: c assembly bios

我可以使用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:
    }


}

1 个答案:

答案 0 :(得分:0)

很抱歉发布这个"回答&#34 ;;我想发布这个"评论"但是太长了......

不同的编译器具有不同的内联汇编语法。这意味着以下行的正确语法:

    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;
...

请注意,有些编译器将关键字命名为&#34; _far&#34;或&#34; __远&#34;而不是&#34;远&#34;。

第三个问题是某些(错误的)BIOS要求ES等于来自disk_pack的段值,第四个问题是许多编译器要求内联汇编代码不修改任何寄存器(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;

在我看来&#34; #pragma pack&#34;不应该是必要的,因为结构中的所有元素都是正确对齐的。