Could you check if my interrupt wrapper makes sense?
Posted: Fri Nov 17, 2023 1:27 am
Hello,
I'm starting to work on interrupts for a 64bits OS written in Nim and I'm unsure if my interrupt caller is correct or not, as I get weird values from the interrupt stack frame.
Right now I have an interrupt table setup and the interrupt gets called successfully, although I get infinite interrupts I'm not too worried about that.
What I'd like to know, before going further, is if my interrupt calling logic makes sense because I'm bad at assembly.
The full code is here:
https://pastebin.com/ie4NxYiZ
The part I'm unsure about is the logic of my assembly:
```
push %rax
push %rcx
push %rdx
push %r8
push %r9
push %r10
push %r11
enter $16, $0
mov %rsp, %rax
add $80, %rax
push [%rax]
add $32, %rax
push %rax
call errorHandler
leave
pop %r11
pop %r10
pop %r9
pop %r8
pop %rdx
pop %rcx
pop %rax
iretq
```
The logic is the following:
I push all the volatile registers so they don't get lost if the callee uses them.
With enter, I assign 16 bytes to the stack frame of the callee, because I intend to pass it a pointer to the start of the interrupt information, and an error code (uint64).
Then I get the address that's 80 bytes above RSP. Because I subtracted 16 bytes to RSP with enter, and 7*8 bytes by pushing the registers, and the error code should be 8 bytes above that. So 16+56+8=80
I push the value at that address so it becomes the second argument passed to my caller.
Then I go up further 32 bytes, because the interrupt information is 40 bytes total in amd64.
And I push that address as a pointer to the interrupt information struct.
Then I call my error handler, leave it, pop all the volatile registers and return from my interrupt.
Does that make sense?
I'm starting to work on interrupts for a 64bits OS written in Nim and I'm unsure if my interrupt caller is correct or not, as I get weird values from the interrupt stack frame.
Right now I have an interrupt table setup and the interrupt gets called successfully, although I get infinite interrupts I'm not too worried about that.
What I'd like to know, before going further, is if my interrupt calling logic makes sense because I'm bad at assembly.
The full code is here:
https://pastebin.com/ie4NxYiZ
The part I'm unsure about is the logic of my assembly:
```
push %rax
push %rcx
push %rdx
push %r8
push %r9
push %r10
push %r11
enter $16, $0
mov %rsp, %rax
add $80, %rax
push [%rax]
add $32, %rax
push %rax
call errorHandler
leave
pop %r11
pop %r10
pop %r9
pop %r8
pop %rdx
pop %rcx
pop %rax
iretq
```
The logic is the following:
I push all the volatile registers so they don't get lost if the callee uses them.
With enter, I assign 16 bytes to the stack frame of the callee, because I intend to pass it a pointer to the start of the interrupt information, and an error code (uint64).
Then I get the address that's 80 bytes above RSP. Because I subtracted 16 bytes to RSP with enter, and 7*8 bytes by pushing the registers, and the error code should be 8 bytes above that. So 16+56+8=80
I push the value at that address so it becomes the second argument passed to my caller.
Then I go up further 32 bytes, because the interrupt information is 40 bytes total in amd64.
And I push that address as a pointer to the interrupt information struct.
Then I call my error handler, leave it, pop all the volatile registers and return from my interrupt.
Does that make sense?