2014-04-03 34 views
3

我正在學習Linux源代碼以瞭解它如何獲取內存映射。我認爲它首先呼叫detect_memory(),其定義爲here。該函數調用在同一個文件中定義的detect_memory_e820()detect_memory_e820()在48個電話intcall這是這樣定義的:需要幫助瞭解Linux內核的BIOS中斷調用

.code16gcc 
    .text 
    .globl intcall 
    .type intcall, @function 
intcall: 
    /* Self-modify the INT instruction. Ugly, but works. */ 
    cmpb %al, 3f 
    je 1f 
    movb %al, 3f 
    jmp 1f  /* Synchronize pipeline */ 
1: 
    /* Save state */ 
    pushfl 
    pushw %fs 
    pushw %gs 
    pushal 

    /* Copy input state to stack frame */ 
    subw $44, %sp 
    movw %dx, %si 
    movw %sp, %di 
    movw $11, %cx 
    rep; movsd 

    /* Pop full state from the stack */ 
    popal 
    popw %gs 
    popw %fs 
    popw %es 
    popw %ds 
    popfl 

    /* Actual INT */ 
    .byte 0xcd  /* INT opcode */ 
3: .byte 0 

    /* Push full state to the stack */ 
    pushfl 
    pushw %ds 
    pushw %es 
    pushw %fs 
    pushw %gs 
    pushal 

    /* Re-establish C environment invariants */ 
    cld 
    movzwl %sp, %esp 
    movw %cs, %ax 
    movw %ax, %ds 
    movw %ax, %es 

    /* Copy output state from stack frame */ 
    movw 68(%esp), %di /* Original %cx == 3rd argument */ 
    andw %di, %di 
    jz 4f 
    movw %sp, %si 
    movw $11, %cx 
    rep; movsd 
4: addw $44, %sp 

    /* Restore state and return */ 
    popal 
    popw %gs 
    popw %fs 
    popfl 
    retl 
    .size intcall, .-intcall 

我的問題是,我無法弄清楚什麼是DX寄存器的在這一點上的價值:movw %dx, %si和它是從哪裏來的。

回答

4

請注意,makefile爲編譯16位C代碼指定了-mregparm=3。如果可能,這指示編譯器將前3個參數放入寄存器eax,edxecx。因此,dx的值將成爲第二個參數&iregs。還要注意的評論進一步下降,確認這一點:/* Original %cx == 3rd argument */

我覺得很有趣,你有沒有問題,在一開始,有關如何al獲得中斷號的價值:)