我想在COM1不使用 BIOS 中斷 14h 的情況下使用串行埠,為此我正在按照osdev 上的教程進行操作,但是在初始化程序中遇到了一些問題。(我對 asm 和 bios 相關的東西很陌生,所以我的代碼可能非常錯誤,或者可能需要在初始化串行埠之前初始化其他東西)
我當前的代碼看起來像這樣,應該是他們的 C 代碼的直接翻譯。
%macro outb 2
mov dx, %1
mov al, %2
out dx, al
%endmacro
%macro inb 1
mov dx, %1
in al, dx
%endmacro
bits 16
org 0x7c00 ;; set the origin at the start of the bootloader address space
xor ax, ax
mov dx, ax
mov es, ax
mov fs, ax
mov gs, ax
serial_init:
outb [com1 1], 0x00 ;; disable all interrupts
outb [com1 3], 0x80 ;; enable DLAB (set baud rate divisor)
outb [com1 0], 0x03 ;; Set divisor to 3 (lo byte) 38440 baud
outb [com1 1], 0x00 ;; (hi byte)
outb [com1 3], 0x03 ;; 8 bits, no parity, one stop bit
outb [com1 2], 0xc7 ;; enable fifo, clear them, with 14-byte threshold
outb [com1 4], 0x0b ;; IRQs enabled, RTS/DSR set
outb [com1 4], 0x1e ;; set in loopback mode, test the serial chip
outb [com1 0], 0xae ;; test serial chip
hang:
jmp hang
com1:
dw 0x3f8
times 510-($-$$) db 0
dw 0xaa55
我有一些除錯原語和一切,似乎很順利,直到outb [com1 0], 0x03之后的行,如果我讀取行控制暫存器,[com1 5]我會得到一個錯誤,但我不確定如何解釋它(這似乎是一個與停止位相關的錯誤,錯誤 3)
uj5u.com熱心網友回復:
給定outb宏定義,NASM 會將您的outb [com1 1], 0x00宏呼叫擴展為:
mov dx, [com1 1]
mov al, 0x00
out dx, al
由于方括號,第一條指令DX將從記憶體加載,遺憾的是它不包含預期的埠地址(0x03F9)!你得到的是 0x0003,它由存盤在com1的字的高位元組和記憶體中的下一個位元組組成,由于times零填充,它恰好是 0 。
為您辯護,維基文章https://wiki.osdev.org/Serial_Ports確實使用方括號,當它說您應該將資料發送到 eg 時[PORT 1]。然而,這些括號與匯編編程語言中使用的相同括號無關。
C 代碼片段更清晰。它define PORT 0x3f8在匯編中變成了PORT equ 0x03F8. 和outb(PORT 1, 0x00)指令變為outb PORT 1, 0x00組裝。這次 NASM 會將你的outb宏擴展為這 3 條指令:
mov dx, PORT 1 ; Same as `mov dx, 0x03F9`
mov al, 0x00
out dx, al
給出的 C 代碼供參考:
define PORT 0x3f8 // COM1
static int init_serial() {
outb(PORT 1, 0x00); // Disable all interrupts
outb(PORT 3, 0x80); // Enable DLAB (set baud rate divisor)
outb(PORT 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
outb(PORT 1, 0x00); // (hi byte)
outb(PORT 3, 0x03); // 8 bits, no parity, one stop bit
outb(PORT 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
outb(PORT 4, 0x0B); // IRQs enabled, RTS/DSR set
outb(PORT 4, 0x1E); // Set in loopback mode, test the serial chip
outb(PORT 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent)
if(inb(PORT 0) != 0xAE) {
return 1;
}
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
outb(PORT 4, 0x0F);
return 0;
}
如果我讀了線路控制暫存器
[com1 5]...
準確性將是對該硬體進行編程的關鍵。甚至對于一般的編程來說也是如此。
該線路控制暫存器(LCR)是在03FB(PORT 3)。
的線狀態暫存器(LSR)是在03FD(PORT 5)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/313728.html
上一篇:為什么“add#0x10,sp”向sp添加16位,而“add#0x8,sp”僅添加8位?(微腐敗CTF,“庫斯科”舞臺)
