Hi,
alberinfo wrote:
this is the bootloader code:
This isn't boot loader code - you're probably using GRUB as the boot loader.
alberinfo wrote:
Code:
BITS 32
section .text
align 4
dd 0x1BADB002
dd 0x00
dd - (0x1BADB002+0x00)
global start
extern main
start:
cli
lidt [idt_info]
smsw ax
and eax, 1
je callmain
mov ebp, esp
push dword [ebp+4]
push dword [ebp+8]
pushfs
or dword [esp], (1 << 17)
push dword [ebp+12]
push dword [ebp+16]
iret
callmain:
call main
hlt
section .text
idt_info:
idt_start dw 0
idt_end dw idt_start - 1
You're using sections "strangely". Typically the ".text" section only contains executable code and not data (and data like "idt_info" should be in a ".data" or ".rodata" section). Also note that normally you'd have a special section for the multi-boot header so that you can write a linker script that ensures the multi-boot header is within the first 8 KiB of the file (which is required by multi-boot).
alberinfo wrote:
why it fails!!??
It fails to link because (with "dw idt_start - 1") you're asking for a 16-bit piece of data ("dw") that contains a 32-bit address (the result of "idt_start - 1") and the linker can't figure out how to make 32 bits of stuff fit in 16 bits of space.
Note that this is all very wrong, and that it looks like you're using a variation of "brute force coding practices" where you randomly change lines of code with no understanding of what the code is supposed to do and then wondering why nothing works. For example, you can't just set a single bit and expect virtual8086 mode to work, and "IRET to virtual 8086 mode" requires a lot more on the stack (the values to use for all segment registers). You will need to read and understand the part of the Intel manual that describes all of the details of virtual8086 mode (which includes requiring a valid GDT and a valid TSS descriptor, and a valid IDT with a general protection fault handler that emulates a bunch of "sensitive" instructions - e.g. CLI, STI, IN, OUT, HLT, ...).
alberinfo wrote:
now, there's something strange.there i call smsw ax, but why ax, and not eax??it's the code ok?
Once upon a time (80286) Intel created a horrible 16-bit protected mode that had a 16-bit "machine status word", and had an instruction (smsw) to set the machine status word. Not long after that Intel added a lot of changes (including adding support for 32-bit, adding paging, adding hardware task switching, adding virtual8086 mode, ...) and added a set of 32-bit control registers and new instructions (like "mov cr0, ...") for the new control registers. For backward compatibility the obsolete 16-bit machine status word became the lowest 16 bits of the new 32-bit "CR0" control register.
Essentially, 32-bit didn't exist when SMSW was created, and then SMSW was deprecated when 32-bit was introduced so Intel had no reason to make it work for 32-bit.
alberinfo wrote:
UPDATE: now solution is that it isnt pushfs, it's pushfd.
For NASM, there's a "warn on orphan labels" command line option (that should be enabled by default?) that you should be using to make sure that simple typos (e.g. "pushfs") don't get treated as labels (e.g. like "pushfs: ") and accepted by the assembler.
Cheers,
Brendan