Stack is overwritten by a function call

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
zmz4
Posts: 4
Joined: Sun Jan 22, 2017 1:21 pm

Stack is overwritten by a function call

Post by zmz4 »

I'm having this weird issue where some of the stack is being overwritten by a function call.

Specifically, I have an IRQ handler in assembly that calls a general c irq_handler(), which calls the specific handler, in this case the one for the PIT timer. The assembly IRQ handler saves the state to the stack, so it's important that the general irq_handler() and the timer handler do not disrupt it. The problem seems to be that in the timer handler, the assembled code does not respect things that have previously been pushed to the stack. Here's the disassembled version and the c code from gdb:

P.S. I know it's a little weird to have the printf with an argument that doesn't get used, that was just a test, it has the same behavior when it just takes a single string.

Code: Select all

   │9       void timer_handler(regs_t r) {                                                                          │
   │10              timer_ticks++;                                                                                  │
   │11                                                                                                              │
   │12          //printf("tick\n");                                                                                 │
   │13          //switch_task();                                                                                    │
   │14          //printf("tock\n");                                                                                 │
   │15                                                                                                              │
   │16              if (timer_ticks % hz == 0) {                                                                    │
B+>│17                      printf("O",0);                                                                          │
   │18              }                                                                                               │
   │19      } 

Code: Select all

   │0xc01042d0 <timer_handler>      mov    0xc010b904,%eax                                                          │
   │0xc01042d5 <timer_handler+5>    add    $0x1,%eax                                                                │
   │0xc01042d8 <timer_handler+8>    cltd                                                                            │
   │0xc01042d9 <timer_handler+9>    mov    %eax,0xc010b904                                                          │
   │0xc01042de <timer_handler+14>   idivl  0xc01081a0                                                               │
   │0xc01042e4 <timer_handler+20>   test   %edx,%edx                                                                │
   │0xc01042e6 <timer_handler+22>   je     0xc01042f0 <timer_handler+32>                                            │
   │0xc01042e8 <timer_handler+24>   repz ret                                                                        │
   │0xc01042ea <timer_handler+26>   lea    0x0(%esi),%esi                                                           │
B+>│0xc01042f0 <timer_handler+32>   movl   $0x0,0x8(%esp)                                                           │
   │0xc01042f8 <timer_handler+40>   movl   $0xc010869f,0x4(%esp)                                                    │
   │0xc0104300 <timer_handler+48>   jmp    0xc0106920 <printf>                                                      │
   │0xc0104305                      lea    0x0(%esi,%eiz,1),%esi                                                    │
   │0xc0104309                      lea    0x0(%edi,%eiz,1),%edi

I think the issue is at instruction 0xc01042f8 and 0xc01042f0. The assembly uses space in the stack for the arguments to printf, but it never allocates space for them at the beginning of the function. Could someone with more experience with assembly give any insight as to what might be the problem? I use printf a lot, and this has never been an issue before. To me it seems like the assembly is almost missing an instruction to sub from esp.

Any insight is appreciated. If any other code would be helpful, like my assembly IRQ handler, I can post that as well.
Thanks,
Zack
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Stack is overwritten by a function call

Post by Octocontrabass »

You've made this mistake. Even if you're not following that particular tutorial, read that section anyway. It explains the problem and potential solutions.
Post Reply