I'm feeling very stupid in this moment, because I just found out that all of those problems are caused by a stupid error.
The line
Code: Select all
pushq fun
Code: Select all
pushq $fun
Thank you again, and sorry if I wasted your time.
Code: Select all
pushq fun
Code: Select all
pushq $fun
I'd assume that "pushw $8" stores 2 bytes on the stack, the "pushq fun" stores 8 more bytes (for a total of 10 bytes so far); and then the "retfq" takes 16 bytes from the stack leaving you with a corrupted mess.lodo1995 wrote:I suppose I should use a far jump, but this code does not work (AT&T syntax):Code: Select all
mov %rax, %cr3 # load paging structures (it works) lgdt 6(%rcx) # load gdt (it works) mov $100, %rsp # update stack pointer (it works) # now what I tried unsuccessfully: pushw $8 # new code segment selector pushq fun # function to execute next retfq # far return (pops address and code segment)
Code: Select all
mov %rax, %cr3
lgdt 6(%rcx)
mov $128, %rsp
pushq $8
pushq $update_segments
retfq
update_segments:
mov $16, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
That's true, when in long mode, the GDT is only used to check permissions of segments. But you still have to load into the registers the offsets to the GDT entries (so that CPU knows which segments to check permissions for). The base and limit values into the GDT are ignored for every segment register. For FS and GS, special MSR are provided with their bases (if needed).intx13 wrote:I thought that only FS and GS could be adjusted in long mode, and the others were forced to a base address of 0000?
http://www.andrea-allievi.com/blog/x64- ... game-over/