1.8088CPU复位时,CS=FFFFH,IP=0000H,因此在ROM的逻辑地址FFFF:0000(FFF0H)处一般要防止一个长跳转指令LJMP(机器码位EAH)
2.写一个完整的8086汇编程序,通过查询方式检测串口接收符串‘r’,然后从内存地址FFFF:0000H开始发送16字节数据。程序使用18.432MHz时钟的16550 UART,波特率9600
3.程序
; 串口查询接收'r'后发送内存数据程序
; 硬件配置:
; PC16550 基地址: 100H
; 时钟频率: 18.432MHz
; 波特率: 9600 bps
; 数据源: FFFF:0000H 开始的16字节内存
ORG 100H
JMP START
; 数据段
WAIT_MSG DB 'Waiting for "r"...', 0Dh, 0Ah, 0
SENDING_MSG DB 'Sending 16 bytes...', 0Dh, 0Ah, 0
DONE_MSG DB 'Transfer complete!', 0Dh, 0Ah, 0
; 16550寄存器偏移地址
UART_BASE EQU 100H
RBR_THR EQU UART_BASE + 0 ; 接收/发送寄存器
LSR EQU UART_BASE + 5 ; 线路状态寄存器
LCR EQU UART_BASE + 3 ; 线路控制寄存器
DLL EQU UART_BASE + 0 ; 除数锁存低字节 (DLAB=1)
DLM EQU UART_BASE + 1 ; 除数锁存高字节 (DLAB=1)
; 初始化UART (波特率9600, 18.432MHz时钟)
INIT_UART:
; 设置波特率除数(9600 @ 18.432MHz)
MOV DX, LCR
MOV AL, 80H ; 设置DLAB=1
OUT DX, AL
MOV DX, DLL ; 除数锁存低字节
MOV AL, 78H ; 120 = 78H
OUT DX, AL
MOV DX, DLM ; 除数锁存高字节
MOV AL, 00H ; 高位为0
OUT DX, AL
; 设置线路参数: 8位数据, 1停止位, 无校验
MOV DX, LCR
MOV AL, 03H ; 8N1, DLAB=0
OUT DX, AL
; 禁用中断
MOV DX, UART_BASE + 1 ; IER
MOV AL, 00H
OUT DX, AL
RET
; 发送单个字符
; 输入: AL = 要发送的字符
SEND_CHAR:
PUSH DX
PUSH AX
; 保存字符
MOV AH, AL
SEND_WAIT:
; 检查发送保持寄存器是否为空
MOV DX, LSR
IN AL, DX
TEST AL, 20H ; 检查THRE位(bit5)
JZ SEND_WAIT ; 不为空则等待
; 发送字符
MOV DX, RBR_THR
MOV AL, AH
OUT DX, AL
POP AX
POP DX
RET
; 接收单个字符
; 输出: AL = 接收到的字符
RECV_CHAR:
PUSH DX
RECV_WAIT:
; 检查接收数据就绪
MOV DX, LSR
IN AL, DX
TEST AL, 01H ; 检查DR位(bit0)
JZ RECV_WAIT ; 无数据则等待
; 读取字符
MOV DX, RBR_THR
IN AL, DX
POP DX
RET
; 发送字符串
; 输入: DS:SI = 字符串地址(以0结尾)
SEND_STRING:
PUSH SI
PUSH AX
SEND_STR_LOOP:
LODSB ; 从[DS:SI]加载字符到AL, SI++
OR AL, AL ; 检查是否结束(AL=0)
JZ SEND_STR_DONE ; 是则结束
CALL SEND_CHAR ; 发送当前字符
JMP SEND_STR_LOOP ; 继续发送
SEND_STR_DONE:
POP AX
POP SI
RET
; 发送内存块
; 输入: ES:BX = 数据起始地址
; CX = 数据长度(字节数)
SEND_MEMORY:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
; 发送状态消息
MOV SI, OFFSET SENDING_MSG
CALL SEND_STRING
; 设置计数器
MOV CX,16
SEND_MEM_LOOP:
; 读取内存字节
MOV AL, ES:[BX]
; 发送字节
CALL SEND_CHAR
; 更新指针和计数器
INC BX
LOOP SEND_MEM_LOOP
; 发送完成消息
MOV SI, OFFSET DONE_MSG
CALL SEND_STRING
POP DX
POP CX
POP BX
POP AX
RET
; 主程序
START:
; 初始化UART
CALL INIT_UART
AGAIN:
; 显示等待消息
MOV SI, OFFSET WAIT_MSG
CALL SEND_STRING
; 等待接收字符'r'
WAIT_FOR_R:
CALL RECV_CHAR
CMP AL, 'r' ; 检查是否收到'r'
JNE WAIT_FOR_R ; 不是则继续等待
; 收到'r'后发送内存数据
MOV AX, 0ffffH ; 设置段地址0000H
MOV ES, AX
MOV BX, 0000H ; 设置偏移地址2000H
CALL SEND_MEMORY ; 发送512字节数据
JMP AGAIN
; 程序结束
MOV AH, 4CH
INT 21H
DB 55H,55H,55H,55H,55H
END START
4.验证