【发布时间】:2013-12-29 08:13:59
【问题描述】:
我正在学习 i8086 实模式编程。
在第一个 .S 程序集 cdoe 文件中:
.intel_syntax noprefix
/* _a20en defined in another .S file */
.section .text
.code16
.extern _a20en
/* code entry is 0x7c00, defined in BIOS */
entry:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov gs, ax
mov sp, 0x7c00
mov ax, 0xb800
mov fs, ax
cld
call _a20en
call _a20en
/* send string '8086' to video ram */
mov byte ptr fs : [0], '8'
mov byte ptr fs : [1], 0x01
mov byte ptr fs : [2], '0'
mov byte ptr fs : [3], 0x01
mov byte ptr fs : [4], '8'
mov byte ptr fs : [5], 0x01
mov byte ptr fs : [6], '6'
mov byte ptr fs : [7], 0x01
jmp . /* stop here */
第二个.S汇编代码文件:
.intel_syntax noprefix
.section .text
.code16
.global _a20en
_a20en:
enter 2, 0
push ax
in al, 0x92
or al, 0x02
out 0x92, al
pop ax
leave
ret
组装后,链接并运行。我在屏幕上看不到字符串“8086”。在 bochs 中调试后,我发现问题出在 2 'call _a20en' 指令中。如果我将 2 行更改为:
lea bx, _a20en
call bx
call bx
代码运行良好。 如果只使用一条“call _a20en”指令,代码也可以正常工作。
真正的问题是在'call _a20en'指令执行中。 push ip 后,跳转到'jmp'。指令,死循环。真正的目的地跳转地址是_a20en,距离'jmp' 2 个字节。说明。
我不知道 2 字节偏移量是如何生成的。组装和链接时没有警告。
【问题讨论】:
-
您应该将此代码范围缩小到仅用于演示问题所需的代码。
-
您使用的是哪个汇编程序?另外,您使用哪些命令行调用来组装和链接?
-
Mingw32,gnu 工具链,windows 版本。 gcc 4.7.1,作为 2.22
-
您似乎没有在该内联链接器脚本中指定 0x7C00 原点。请记住,BIOS 会跳转到 0000:7C00,而不是 07C0:0000。我本来希望相对工作和绝对 lea 失败,所以也许我错了
-
哦,您能否发布生成的二进制图像,以便我们分解它们并仔细检查编码?