general assembly help
general assembly help
Ok, So I wrote a small program that tests to make sure I can get interrupts working in pmode by making 50 generic interrupt handlers that just return and making the kbd int print to the screen. This code is loaded by the boot loader to 0x00100001, just after the 1MB mark. Now I know the loader code works because before I loaded a different test program and verified it ran, but i run into a weird bug with the interrupt program. From what I debugged, it fails at a jmp instruction I have near the end, and dissassembled, this instruction looks like jmp ffffff01.
I dont have the exact address, but I know for sure it had a lot of f's and was a high address when it shouldve been a local jump. I have no clue what to think about this. should 32 bit pmode code be align 4 or align 8? Thats my only guess, but I still cant see how nasm is generating that address for a label in a 1500 byte program that starts at 0
I dont have the exact address, but I know for sure it had a lot of f's and was a high address when it shouldve been a local jump. I have no clue what to think about this. should 32 bit pmode code be align 4 or align 8? Thats my only guess, but I still cant see how nasm is generating that address for a label in a 1500 byte program that starts at 0
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: general assembly help
Maybe you could show us some code? Also, 0x00100000 is where people usually load, you're wasting one precious byte
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: general assembly help
ok, as soon as i get home from work, i will post the code, the instruction where its failing, and
also the way that instruction looks dissassembled.
also the way that instruction looks dissassembled.
Re: general assembly help
here is the code:
Now the problem is that for some reason none of the jumps are resolving to the right address except the very first one. This is the disassembled code through bochs. all those jumps are the isr definitions and they should all be jumping to the same place, namely 0x00100001.
Code: Select all
[bits 32] ;[org 0x0011]
[org 0x0001]
jmp idt_install
KERNEL_CODE_SEL equ 0x08
;;;;;;;;;;;;;;;;;;;;;; JUST FOR NOW
isr_common_stub:
; ack the pic
mov al, 0x20
out 0x20, al
iret
%macro CREATE_ISR 1
isr#%1:
jmp isr_common_stub
%endmacro
%assign i 0
%rep 51
CREATE_ISR i
%assign i (i + 1)
%endrep
; ------------------------------------------
; Interrupt Descriptor Table
; ------------------------------------------
; idt_entry is
; 0 base_low.w
; 2 code_segment_selector.w
; 4 always0.b
; 5 flags.b
; 6 base_high.w
; end idt_entry = 8 bytes
;;;;;;;; section '.data'
idtr: dw idt_end - idt - 1 ; IDT limit
dd idt ; address of IDT
; ------------------------------------------
%macro make_idt_entry 0
dw 0 ; isr0 and 0xFFFF
dw KERNEL_CODE_SEL
db 0
db 0x8E ; Access flags: Running in kernel mode (| 0x60 for usermode)
dw 0 ; (isr#num shr 16) and 0xFFFF
%endmacro
idt:
%rep 51
make_idt_entry ;(32+16+3) ; exceptions+interrupts+syscall
%endrep
idt_end:
; IDT -> ISR installation
%macro set_idt_entry 1
; base_lo = isr0 and 0xFFFF
mov eax, isr#%1
mov [idt+ %1 * 8], ax
; base_hi = (isr0 >> 16) and 0xFFFF
shr eax, 16
mov [idt + %1 * 8 + 6], ax
%endmacro
idt_install:
lidt [idtr]
; remap irq here
mov al, 0x11 ; send ICW1
out 0x20, al
out 0xA0, al
; ICW2
mov al, 0x20 ; remap 1st half of PIC
out 0x21, al
mov al, 0x28 ; then 2nd half
out 0xA1, al
; ICW3
mov al, 4
out 0x21, al
mov al, 2
out 0xA1, al
; ICW4
mov al, 0x01
out 0x21, al
out 0xA1, al
; disable interrupts
; mov al, 0xFF
; out 0x21, al
cli
%assign i 0
%rep 50
set_idt_entry i
%assign i (i+1)
%endrep
jmp setup_kbd
;;; CUSTOM TEST CODE
kbd_int:
pusha
in al, 0x60
mov ecx, [counter]
mov ebx, 0xb8000
mov [es:ebx+ecx], al
inc ecx
mov [counter], ecx
popa
jmp isr_common_stub
; set 9th idt descriptor to point to kdb_int
setup_kbd:
mov eax, kbd_int
mov [idt + 9 * 8], ax
; base_hi = (isr0 >> 16) and 0xFFFF
shr eax, 16
mov [idt + 9 * 8 + 6], ax
mov ax, 0x18
mov es, ax
sti
;; hang here to see if everything(or anything) works
wait_and_see:
jmp wait_and_see
counter db 0
Now the problem is that for some reason none of the jumps are resolving to the right address except the very first one. This is the disassembled code through bochs. all those jumps are the isr definitions and they should all be jumping to the same place, namely 0x00100001.
Code: Select all
00100001: ( ): jmp .+0x00000209 ; e909020000
00100006: ( ): mov al, 0x20 ; b020
00100008: ( ): out 0x20, al ; e620
0010000a: ( ): iretd ; cf
0010000b: ( ): jmp .+0xfffffff9 ; ebf9
0010000d: ( ): jmp .+0xfffffff7 ; ebf7
0010000f: ( ): jmp .+0xfffffff5 ; ebf5
00100011: ( ): jmp .+0xfffffff3 ; ebf3
00100013: ( ): jmp .+0xfffffff1 ; ebf1
00100015: ( ): jmp .+0xffffffef ; ebef
00100017: ( ): jmp .+0xffffffed ; ebed
00100019: ( ): jmp .+0xffffffeb ; ebeb
0010001b: ( ): jmp .+0xffffffe9 ; ebe9
0010001d: ( ): jmp .+0xffffffe7 ; ebe7
0010001f: ( ): jmp .+0xffffffe5 ; ebe5
Re: general assembly help
Post fixed by the code tags police Please use code tags in future.
Cheers,
Adam
Cheers,
Adam
Re: general assembly help
the only thing i can think of is that these are unsigned numbers and showing up as negative jumps, but i thought a jump was to a real offset, not a relative offset.
Re: general assembly help
Hi,
This doesn't explain why the first jump isn't also a relative jump - I'm guessing you didn't enable the optimizer (e.g. "nasm -Ox") and the assembler couldn't figure out if the target could be reached with a relative jump or not because it only did a single pass.
Finally, that first jump looks like it jumps to the wrong address, while the relative jumps look like they jump to the correct address. The first jump is an absolute jump, which means the assembler needs to know which address the target will be. For the relative jumps, the assembler only needs to know how many bytes to jump forward or backward and doesn't need to know the address the target will be. From this I'd assume you didn't put "org 0x00100001" at the start of your code (and maybe you put "org 0x00000209" instead???); or perhaps your linker script isn't right.
Cheers,
Brendan
The CPU supports absolute jumps and relative jumps (and indirect jumps). Relative jumps cost 2 bytes. Absolute jumps cost 3 bytes (16-bit code) or 5 bytes (32-bit code). Most assemblers, etc will use a relative jump to reduce code size (if the target can be reached with "eip + 8-bit signed offset").yemista wrote:the only thing i can think of is that these are unsigned numbers and showing up as negative jumps, but i thought a jump was to a real offset, not a relative offset.
This doesn't explain why the first jump isn't also a relative jump - I'm guessing you didn't enable the optimizer (e.g. "nasm -Ox") and the assembler couldn't figure out if the target could be reached with a relative jump or not because it only did a single pass.
Finally, that first jump looks like it jumps to the wrong address, while the relative jumps look like they jump to the correct address. The first jump is an absolute jump, which means the assembler needs to know which address the target will be. For the relative jumps, the assembler only needs to know how many bytes to jump forward or backward and doesn't need to know the address the target will be. From this I'd assume you didn't put "org 0x00100001" at the start of your code (and maybe you put "org 0x00000209" instead???); or perhaps your linker script isn't right.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: general assembly help
i put [org 0x0001] at the start of the code, not [org 0x00100001]. Maybe this is the problem? I will try again once I get home. How do you make it so that you can decide if it will be a relative jump or an absolute jump? I dont think that first jump is wrong, because the segmentation fault occurs at a jump much further down in the code, which means it must execute that first jump correctly.
Re: general assembly help
i changed org to 0x00100001, and i noticed that for some reason, it is falling through the first jmp in the file. I get the failure at the iret, which it should not be hitting if it does the jump correctly
Re: general assembly help
Hi,
Absolute jumps are only done for far jumps (e.g. "jmp seg:offset"), and indirect jumps are absolute too (e.g. "jmp [foo]" where there's an absolute address stored at "foo").
I'm guessing that there's probably lots of other problems elsewhere. I'd also assume you're not using effective debugging techniques to find out what's actually going wrong, and working with misleading symptoms because of that..
Cheers,
Brendan
Telling the assembler your code is running at one address and then running that code at a different address might be part of the problem...yemista wrote:i put [org 0x0001] at the start of the code, not [org 0x00100001]. Maybe this is the problem?
I took a look at the JMP instruction in Intel's manual. All conditional branches (JC, JNE, etc) are always relative and so are normal JMP instructions (e.g. "JMP foo"); where the target of the jump is encoded as either an 8-bit signed number, a 16-bit signed number, or an 16-bit signed number, and is an offset from EIP. This means I was wrong before - the first jump is relative not absolute.yemista wrote:How do you make it so that you can decide if it will be a relative jump or an absolute jump? I dont think that first jump is wrong, because the segmentation fault occurs at a jump much further down in the code, which means it must execute that first jump correctly.
Absolute jumps are only done for far jumps (e.g. "jmp seg:offset"), and indirect jumps are absolute too (e.g. "jmp [foo]" where there's an absolute address stored at "foo").
Given that the first jump actually is relative, changing the ORG won't make any difference (for that jump).yemista wrote:i changed org to 0x00100001, and i noticed that for some reason, it is falling through the first jmp in the file. I get the failure at the iret, which it should not be hitting if it does the jump correctly
I'm guessing that there's probably lots of other problems elsewhere. I'd also assume you're not using effective debugging techniques to find out what's actually going wrong, and working with misleading symptoms because of that..
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.