1

I am new to assembly programming and I am trying to implement a program that asks the user to input two integers. The program should then return the value of the first integer raised to the power of the second integer. I attempt to achieve this by using a loop to multiply the value in RAX over and over again. I believe I have done this correctly but the problem arises when I attempt to call the function pow, resulting in a segmentation fault error. I would like to know what I am doing wrong. The code is below:

.text
welcomeStr: .asciz "\nEnter a non-negative base followed by an exponent:\n"
inputStr:   .asciz "%ld"
outputStr:  .asciz "The result is%ld\n"

.data
base:   .quad 0
exp:    .quad 0 

.global main
main:
    # Prologue
    pushq   %rbp
    movq    %rsp, %rbp

    # Print the welcome message
    movq    $0, %rax
    movq    $welcomeStr, %rdi
    call    printf

    # Get input from user and store in base
    leaq    inputStr(%rip), %rdi
    leaq    base(%rip), %rsi
    call    scanf

    # Get input from user and store in exp
    leaq    inputStr(%rip), %rdi
    leaq    exp(%rip), %rsi
    call    scanf

    call    pow

    # Print the value in rax to the command line
    movq    %rax, %rsi
    movq    $0, %rax
    movq    $outputStr, %rdi
    call    printf

    movq    $0, %rdi
    call    exit

pow:
    # Prologue
    pushq   %rbp
    movq    %rsp, %rbp

    # Load rcx with the value of the exponential and rax with 1
    movq    exp, %rcx
    movq    $1, %rax

loop:
    cmpq    $0, %rcx
    jle     end # Break loop if the value in rcx is less than or equal to 1
    mulq    base
    dec     %rcx # Decrement counter by one
    jmp     loop # Loop again

    # Epilogue
    movq    %rbp, %rsp
    popq    %rbp
    ret
User3952
  • 7
  • 2
  • Use your debugger to figure out the direct cause of the crash. – Jester Sep 14 '20 at 18:17
  • 2
    You need to place `main` in the `.text` section. – fuz Sep 14 '20 at 18:17
  • Also `scanf` is a varargs function just like `printf` so the same rule of setting `al` to zero applies. – Jester Sep 14 '20 at 18:19
  • 2
    The direct cause is that you forgot to define your `end` label. Not sure what the linker picks up instead, but definitely not the address you want :) – Jester Sep 14 '20 at 18:24
  • Ah yes! Thank you Jester, that was it. The segfault error was making me think that I got the calling convention all wrong. Turns out it was just the undefined label. – User3952 Sep 14 '20 at 18:35
  • @Jester: Hmm, you're right. Executable `.data` happens by default unless you avoid it, so even though the code is in `.data` that's not the cause of the segfault. So not really a duplicate. Do we have a Q&A for stray simple label names defined by glibc / CRT letting a program link but then fail at runtime? – Peter Cordes Sep 14 '20 at 19:07

0 Answers0