assembly - How to setup Stack segment in protected mode? -
this problem defined 1 data , stack segment in x86 protected mode selector under gdt. when jmp protected mode, seems can access data section crash when push eax. see following code:
%include "../inc/descriptor.asm" %include "../inc/define.asm" org 7c00h jmp begin ; ----------------------------------------------------------------------- ; const variable stack_base equ 1000000h ; 16m data_base equ 2000000h ; 32m stack_size equ 8000h ; 32k stack_limit equ 1008000h ; 16m + 32k data_size equ 100000h ; 1m ; gdt , ldt ; descriptor base limit property [section .gdt] gdt: descriptor 0, 0, 0 ldt_code32: descriptor 0, seg_code32_len - 1, da_c + da_32 ldt_video: descriptor 0b8000h, 0ffffh, da_drw ldt_stack: descriptor stack_base, stack_size - 1, da_drwa + da_b ldt_data: descriptor data_base, data_size - 1, da_drw gdtlen equ $ - gdt gdtptr dw gdtlen - 1 dd 0 ; selectors slt_code32 equ ldt_code32 - gdt slt_video equ ldt_video - gdt slt_stack equ ldt_stack - gdt slt_data equ ldt_data - gdt ; ----------------------------------------------------------------------- ; real mode code [section .s16] [bits 16] begin: mov ax, cs mov ds, ax ; init 32 bits code section descriptor xor eax, eax mov ax, cs shl eax, 4 add eax, code32 mov word [ldt_code32 + 2], ax shr eax, 16 mov byte [ldt_code32 + 4], al mov byte [ldt_code32 + 7], ah ; prepare loading gdtr xor eax, eax mov ax, ds shl eax, 4 add eax, gdt mov dword [gdtptr + 2], eax lgdt [gdtptr] cli in al, 92h or al, 10b out 92h, al mov eax, cr0 or eax, 1 mov cr0, eax jmp dword slt_code32:0 ; protected mode code [section .s32] [bits 32] code32: mov ax, slt_video mov gs, ax mov ax, slt_stack mov ss, ax mov esp, stack_limit - 16 mov ax, slt_data mov ds, ax mov eax, 012345678h xor edx, edx mov [edx], eax mov edx, [edx] push eax ; **<= crashed here.** ; --------------------------------- ; prepare debug char mov ax, slt_video mov gs, ax mov bh, 0ch mov bl, 'b' mov esi, (80 * 1 + 1) * 2 mov [gs:esi], bx jmp $ ; ; end of prepare debug char ; --------------------------------- push eax pop ebx mov eax, data_base mov dword [eax], ebx mov edi, 0 mov esi, (80 * 1 + 1) * 2 call print_dword jmp $ ; --------------------------------- ; ; prepare debug char ; mov ax, slt_video ; mov gs, ax ; mov bh, 0ch ; mov bl, 'b' ; mov esi, (80 * 1 + 1) * 2 ; mov [gs:esi], bx ; jmp $ ; ; end of prepare debug char ; --------------------------------- seg_code32_len equ $ - code32 times 290 - ($ - $$) db 0 dw 0xaa55 ; command reference: ; nasm protected_mode.asm -o pm.bin ; dd if=pm.bin of=pm.img bs=512 count=1 descriptor.asm:
; ; descriptor base, limit, attr ; base: dd ; limit: dd low 20 bits available ; attr: dw low nibble of higher byte 0 ; %macro descriptor 3 dw %2 & 0ffffh dw %1 & 0ffffh db (%1 >> 16) & 0ffh dw ((%2 >> 8) & 0f00h) | (%3 & 0f0ffh) db (%1 >> 24) & 0ffh %endmacro ; define.asm:
; da_32 equ 4000h da_drw equ 92h da_drwa equ 93h da_c equ 98h da_b equ da_32 da_element_4k equ 8000h ; ; paging entry attribute pg_p equ 1 pg_rw_w equ 2 pg_us_u equ 4
since set segment base stack_base must not add stack pointer. such, mov esp, stack_limit - 16 should mov esp, stack_size - 16.
ps: never set cs, code might break on systems it's not zero.
Comments
Post a Comment