0

I have the following code (I'll print only the lines the program goes through before arriving at the segmentation fault)

    push rbp
    mov  rbp, rsp                                        
    push rax                                                
    push rsi                                    
    push rdi                                    
    push rcx                                    
    push rdx                                    
                                                                                        
    mov ecx, 0Ah                                
    mov esi, 0h                                 
    
    for1:                                       
       cmp esi, DimMatrix * DimMatrix * 2       
       jge for1_end                             
       mov edx, 011h                            
       mov edi, 0h                              
                                
       for2:                                    
          cmp edi, DimMatrix                    
          jge for2_end                          
          mov ax, [m + esi + edi * 2]           
          movsx eax, ax                         
          mov DWORD[number], eax                
          mov DWORD[rowScreen], ecx             
          mov DWORD[colScreen], edx             
          call showNumberP1
showNumberP1:
   push rbp
   mov  rbp, rsp
                                    
   push rax                         
   push rbx                         
   push rcx
   push rdx                         
                                    
   mov eax, [number]                
   mov cl, 0h                       
   mov ebx, 0Ah
   if1: 
      cmp eax, 000F423Fh            
      jle if1_end                   
      mov eax, 000F423Fh            
   if1_end:                         
   for: 
      cmp cl, 6h                    
      jge for_end                   
      mov BYTE[charac], 20h         
      if2:
         cmp eax, 0h                
         jle if2_end                
         mov edx, 0h                
         div ebx                    
         mov BYTE[charac], dl       
         add BYTE[charac], 30h      
         
      if2_end:
      call gotoxyP1

gotoxyP1 is an nasm subroutine that calls on the correspoding C function which has one line:

printf("\x1B[%d;%dH",rowScreen,colScreen);

And that's where to program crashes with a segmentation fault.

number, rowScreen and colScreen are all int variables in the C program, and charac is a char variable. showNumberP1 works fine when tested on its own. Hoping somebody can find what's causing the segmentation fault, because I can't see it.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
daniel
  • 118
  • 1
  • 7
  • [Stack alignment](https://stackoverflow.com/questions/49391001/why-does-the-x86-64-amd64-system-v-abi-mandate-a-16-byte-stack-alignment/49397524#49397524) is my first guess. I assume from the term "segmentation fault" that this is on some Unix flavor, where the prevailing SysV C ABI requires 16-byte stack alignment, which your program doesn't maintain. Some C functions don't mind, but common `printf` implementations use SSE aligned loads and stores, which will indeed segfault if the stack is not aligned as the ABI demands. – Nate Eldredge Nov 06 '22 at 18:45
  • If that's not it, then please turn your code into a [mcve] that people can test. Like most people here, I find it infinitely easier to find bugs in someone's code if I can actually run the code in a debugger, than if I have to just stare at it and think hard. Note that [mcve] means we should be able to paste your exact code into a file, compile it and run, without further changes. Include all the header files, main functions, and so forth. But omit or stub out code that isn't needed to reproduce the bug. – Nate Eldredge Nov 06 '22 at 18:48
  • 2
    Hang on a second, this is 64-bit code? But all your memory accesses are using 32-bit registers and offsets, e.g. `[m + esi + edi * 2]`. That's not gonna work if your program isn't all in the low 4GB of memory, which by default with ASLR it won't be. – Nate Eldredge Nov 06 '22 at 18:50
  • You should be using rip-relative addressing for all your static data, and some of your complex addressing modes will have to be broken down into multiple instructions. See https://stackoverflow.com/questions/43367427/32-bit-absolute-addresses-no-longer-allowed-in-x86-64-linux/46493456#46493456. – Nate Eldredge Nov 06 '22 at 18:53
  • Thanks for all the help! It was a stack alignment problem. I made the last four bits of rsp zero and it everything worked fine. About the memory access and rip-relative addressing: we've been told by the teacher to use -no-pie in gcc when compiling code. Would that be OK or should I use 64bit registers to access memory? – daniel Nov 07 '22 at 03:06
  • With `-no-pie`, using 32-bit registers will work, but I don't think it's a good habit to get into. – Nate Eldredge Nov 07 '22 at 06:39
  • Thank you so much. It is a really interesting topic and I would like to learn more about it on my own time. What readings would you recommend in order to do that? – daniel Nov 07 '22 at 09:26

0 Answers0