尝试打印主引导记录ASCII签名遇空串问题求助(x86汇编)
我尝试打印包含主引导记录(MBR)ASCII签名的字符串,但输出是空串;只有把地址设为0x00或0x20这类值时,才能打印出一些ASCII字符。我刚接触汇编和x86分段,不确定自己操作是否正确。
INT 10H 1300H: 显示字符串
输入参数:
AX = 1300H
BH = 视频页号
BL = 视频属性
CX = 字符串长度
DH,DL = 起始行、列
ES:BP = 文本起始地址
──────────────────────────────────────────────────────────────────
返回值:无
我的代码
// Stack Segment new MovInstruction_Register16Bit_Immediate16Bit(Register8086.AL, offset), new MovInstruction_Segment16Bit_RegisterImmediate16Bit(Register8086.DL, Register8086.AL), new MovInstruction_Register16Bit_Immediate16Bit(Register8086.AH, 0x00), new MovInstruction_Register16Bit_Immediate16Bit(Register8086.CH, size), // Extra Segment new MovInstruction_Register16Bit_Immediate16Bit(Register8086.BL, offset), new MovInstruction_Segment16Bit_RegisterImmediate16Bit(Register8086.AL, Register8086.BL), new MovInstruction_Register16Bit_Immediate16Bit(Register8086.BH, 0x00), // Main new MovInstruction_Register16Bit_Immediate16Bit(Register8086.AL, 0x1300), new MovInstruction_Register8Bit_Immediate8Bit(Register8086.BH, videoPage), new MovInstruction_Register8Bit_Immediate8Bit(Register8086.BL, videoAttribute), new MovInstruction_Register16Bit_Immediate16Bit(Register8086.CL, lengthOfString), new MovInstruction_Register8Bit_Immediate8Bit(Register8086.DH, row), new MovInstruction_Register8Bit_Immediate8Bit(Register8086.DL, column), //new MovInstruction_Register16Bit_Immediate16Bit(Register8086.CH, size), //new MovInstruction_Register16Bit_Immediate16Bit(Register8086.AH, offset), //new MovInstruction_Segment16Bit_RegisterImmediate16Bit(Register8086.AL, Register8086.AH),
反汇编结果
// Stack Segment 0x0000000000000000: B8 00 7C mov ax, 0x7c00 0x0000000000000003: 8E D0 mov ss, ax 0x0000000000000005: BC 00 00 mov sp, 0 0x0000000000000008: BD 01 00 mov bp, 1 // Extra Segment 0x000000000000000b: BB 00 7C mov bx, 0x7c00 0x000000000000000e: 8E C3 mov es, bx 0x0000000000000010: BF 00 00 mov di, 0 // Main 0x0000000000000013: B8 00 13 mov ax, 0x1300 0x0000000000000016: B7 00 mov bh, 0 0x0000000000000018: B3 4D mov bl, 0x4d 0x000000000000001a: B9 00 02 mov cx, 0x200 0x000000000000001d: B6 00 mov dh, 0 0x000000000000001f: B2 00 mov dl, 0 //0x0000000000000021: BD 01 00 mov bp, 1 //0x0000000000000024: BC 00 7C mov sp, 0x7c00 //0x0000000000000027: 8E C4 mov es, sp 0x0000000000000029: CD 10 int 0x10
问题分析与解决
ES:BP地址指向错误
INT 10H 0x1300要求ES:BP指向字符串起始地址,但反汇编中BP被设为0x1,结合ES=0x7c00,实际指向物理地址0x7c00*16 + 0x1 = 0x7c01,如果MBR签名不在这个位置,自然读不到有效字符。- MBR的
0x55AA签名位于扇区最后两个字节,对应偏移地址0x1FE(MBR共512字节,范围0x0000~0x01FF),要打印这个签名的ASCII,需将BP设为0x1FE。
- MBR的
字符串长度设置过大
反汇编中CX=0x200(512字节),会从ES:BP开始读取512字节打印,但大部分内容是不可打印的控制字符或0,导致输出为空。需根据实际字符串长度设置CX,比如打印MBR签名时设为2。寄存器使用注意事项
生成代码中存在寄存器位数匹配错误(比如用8位的AL存16位的0x1300),虽然反汇编中生成器自动修正为AX,但编写时要注意:16位数据必须用16位寄存器存储。分段逻辑澄清
x86物理地址计算公式为段寄存器值*16 + 偏移地址,你将ES设为0x7c00是正确的(MBR加载到物理地址0x7c00,对应段地址0x7c00+偏移0x0),但偏移地址BP必须精准指向目标字符串位置。
修正示例(反汇编部分)
// 修正BP指向MBR签名偏移,CX设为字符串长度 0x0000000000000008: BD FE 01 mov bp, 0x1FE ... 0x000000000000001a: B9 02 00 mov cx, 0x2
内容的提问来源于stack exchange,提问作者Todor Yanev

