今天研究执行流,代码运行到自定义的栈时bochs总是重启。把栈的地址定义到了第三个数据段0x18,在0x7e00处,分出64k(0x10000)空间。段描述符是这样的:
Base4 | G D/B L A + L2.5 | P DLP S + T E W A | Base3 | Base2 | Base1 | L2 | L1 | |
0 0 0 0 0000 | 1 0 0 1 0 1 1 0 | 二进制 | ||||||
00 | 0 0 | 9 6 | 00 | 7e | 00 | ff | ff | 十六进制 |
00 | 00 | 96 | 00 | 7e | 00 | ff | ff | 结果 |
加载运行后,出错。单步调试,都是在压栈的时候bochs里面的虚拟系统重启,仔细研究了一下段描述符,感觉expand down自己理解的可能不对。只管把E位改为0,即段描述符改为expand up,0x000092007e00ffff排除错误。
网上搜索解释,下面是Intel 白皮书原文。
For expand-down data segments, the segment limit has the same function but is interpreted differently. Here, the effective limit specifies the last address that is not allowed to be accessed within the segment; the range of valid offset is from (Effective-limit + 1) to FFFFFFFFH if the B is set and from (effective-limit + 1) to FFFFH is the B is clear; An expand-down segment has maximum size when the segment limit is 0.
最后一句看懂了,limit 为 0时,expand-down段有最大值。感觉理解了老外的想法,expand-up是:limit就是可用的地址范围,expand-down是:limit取反才是可用的范围。
根据这个理解不改E位,把limit全部改为0,实现成功。
放个示例记录一下。
示例代码
[org 0x7c00]
[section .text]
[bits 16]
global _start
mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x1000
xchg bx, bx
mov ax, complate - _start
;mov dl, 0x08
;div dl
;inc ax
mov cx, ax
mov si, _start
mov di, 0x500
cpymem:
mov ax, [si]
mov word [di], ax
add si, 2
add di, 2
loop cpymem
xchg bx, bx
call _16bProgTest1
call _16bProgTest2
xchg bx, bx
cli
lgdt [gdtptr]
mov dx, 0x92
in al, dx
or al, 2
out dx, al
mov eax, cr0
or eax, 1
mov cr0, eax
sti
jmp 8:0
_16bProgTest1:
push bp
mov bp, sp
sub sp, 0x10
push bx
push si
push di
mov ax, 0xAA
pop di
pop si
pop bx
mov sp, bp
pop bp
ret
_16bProgTest2:
push bp
mov bp, sp
sub sp, 0x10
push bx
push si
push di
mov ax, 0xBB
pop di
pop si
pop bx
mov sp, bp
pop bp
ret
gdt:
dq 0
dq 0x_00_40_9e_00_05_00_76_ff
dq 0x_00_40_96_00_7e_00_00_00
dq 0x_00_00_92_00_7e_00_ff_ff
gend:
glen equ gend - gdt
gdtptr:
dw glen
dd gdt
[section .text]
[bits 32]
jmp _start
_start:
mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x10
mov ss, ax
mov esp, 0x2000
xchg bx, bx
call _32bExecStream1
call _32bExecStream2
jmp end
_32bExecStream1:
push ebp
mov ebp, esp
sub esp, 0x10
push ebx
push esi
push edi
mov eax, 0xAAAA
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
_32bExecStream2:
push ebp
mov ebp, esp
sub esp, 0x10
push ebx
push esi
push edi
mov eax, 0xBBBB
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
end:
hlt
complate:
times 510-($-$$) db 0
db 0x55, 0xaa
标签:00,mov,pop,down,关于,push,ax,bx,expand From: https://www.cnblogs.com/erhy/p/18182911