title: SEGSEV, segmentation fault on ENTER opcode
body: <p>(I'm writing in pure x86 assembly for NASM, not in C/C++.)</p>
  
  <p>I'm getting a segmentation fault when the compiled binary runs - I'm aware this is an age old error message, but searching for this specific instance of a seg fault hasn't proved to be fruitful:</p>
  
  <p>gdb suggests that the fault happened at <code>ENTER 616,0</code> at the beginning of a call. I believe it's the same as pushing the old <code>%rbp</code>, storing <code>%rsp</code> into <code>%rbp</code>, and decreasing <code>%rsp</code> for <code>616</code> bytes of local variables.</p>
  
  <p>Does anyone with more experience have hints as to why a segmentation fault can happen here? It seems like a strange place for memory access issues - the only thing that comes to mind is that 616 might be a lot to decrease the value by, but other than that it's baffling me. Is there a limit on the size allowed (other than the total amount of memory available)?</p>
  
  <p>Any help would be much appreciated.</p>
  
  <p>Update:
  If it helps, this isn't the end of a long series of recursive calls:</p>
  
  <pre><code>(gdb) backtrace
  #0  0x00000000004005e0 in user_func ()
  #1  0x0000000000400e69 in if4 ()
  #2  0xffffffffffffffff in ?? ()
  #3  0xffffffffffffffff in ?? ()
  #4  0x0000000000000000 in ?? ()
  
  (gdb) frame 0
  #0  0x00000000004005e0 in user_func ()
  
  (gdb) disassemble
  Dump of assembler code for function user_partition:
  =&gt; 0x00000000004005e0 &lt;+0&gt;:     enterq $0x2b0,$0x0
     0x00000000004005e4 &lt;+4&gt;:     push   %r15
     0x00000000004005e6 &lt;+6&gt;:     push   %r12
     0x00000000004005e8 &lt;+8&gt;:     push   %r13
     0x00000000004005ea &lt;+10&gt;:    push   %r14
     ...
  </code></pre>
  
  <p>Update 2:
  Since the backtrace seems to indicate a corrupted stack pointer, here's some relevant details on what each method call looks like:</p>
  
  <pre><code>user_func:                           
     ENTER      296, 0                         
     PUSH       R13      ; Saving any callee-saved registers used in main body   
     PUSH       R15     
     PUSH       R14     
     PUSH       R12     
     ; Only opcodes to MOV between temp registers and [ RBP - x ]
     MOV        RAX, 0                        
     POP        R12      ; Restoring the callee-saved registers    
     POP        R14
     POP        R15
     POP        R13
     LEAVE                                    
     RET                                      
  </code></pre>
  
  <p>Is it possible that I've done something wrong here in terms of pushing / popping things? The POP before LEAVE seemed right to me...</p>