0

I think I'm missing an important concept when it comes to the assembly stack. I wanted to push the value of the register rcx, since the called function uses this register, but I get a seg fault. I know that if I put push rbx before push rcx (for pop after) the code works. Is there a good reason behind this (to me it seems pointless) ?

.intel_syntax noprefix

.data

wrtfrmt:    .asciz "%c\n"
rdfrmt:     .asciz "%d"

.bss

.lcomm      val, 4

.text

.global main



main:   

    enter 0,0

    lea rdi, rdfrmt
    lea rsi, val
    call scanf

    mov ebx, val        

    lea rdi, rdfrmt
    lea esi, val
    call scanf

    mov ecx, val        


    next:


    push rcx

    lea rdi, rdfrmt
    lea esi, val
    call scanf


    pop rcx
    cmp ebx, val

    loopne next

    jne not_found

    mov esi, 'y'
    jmp print

    not_found:
    mov esi, 'y'

    print:
    lea rdi, wrtfrmt
    call printf

    leave
    ret
monolith937
  • 429
  • 1
  • 4
  • 13
  • 1
    Probably misaligned stack (x86-64 ABI requires 16-byte alignment for the stack pointer on function call [except `_start()`], but since you're using insane instructions (`enter`) I'm not going to even *try* to debug this for you. – EOF Aug 06 '18 at 18:03
  • 1
    Also `printf` and `scanf` are vararg functions hence according to the sysv abi that you seem to be using you need to zero `al`. – Jester Aug 06 '18 at 19:04
  • 1
    Performance reasons. It's faster to not re-align stack memory in every function, and some instructions require aligned memory access, which functions like `scanf/printf` can use in their implementation to speed it up, so they are sensitive to stack alignment and rely on the ABI conditions being fulfilled by the caller. (if you call them incorrectly, they may (and highly likely will) crash) – Ped7g Aug 06 '18 at 20:46
  • 1
    BTW your question title is wrong. You don't have problem to push rcx to stack. You have problem with `scanf` segfaulting when called. Would you search for that, I'm pretty sure there are several duplicates, explaining both stack alignment and vararg requirements in in linux 64 bit ABI (or maybe some other 64 bit ABI too, but I'm interested only into linux OS) - you can verify by keeping only push/pop rcx instructions, and comment out the inner scanf calls, the code will work without segfault, preserving rcx as designed. (but of course you should use debugger to see what the code does). – Ped7g Aug 06 '18 at 20:50
  • i apologize for the inconvenience, but all I could gather from my code was this. Believe it or not it's the first time I hear about stack alignment, so I wouldn't even know what was the issue, hence my badly formulated problem. Was just looking for some insight so I could dig deeper into this, since as you suspected I'm not even sure what the question is, just the problem – monolith937 Aug 07 '18 at 08:37
  • ;) ... don't get distracted by the harsh tone, the point is, that everything in assembly works in very precise terms, so using the calling convention (`call scanf`) without studying the rules (ABI definition) is recipe for disaster. Writing code without using debugger and being capable to pinpoint the problem down to exact spot/value is another recipe for disaster. There's certain "barrier" of basic knowledge when entering asm world, which takes some time+effort to get over it, and until then even the most innocent looking modifications of working examples tend to not work. Keep pushing. – Ped7g Aug 08 '18 at 08:04

0 Answers0