title: Segmentation fault on printf - NASM 64bit Linux
body: <p>I trying to input four floats using <code>scanf</code>, store them onto the stack, and then use <code>vmovupd</code> to copy them over to a register for use. My problem is when I try to output those 4 numbers, the program seg faults at <code>printf</code>. </p>
  
  <p>I presume it is something with the stack but I've tried popping numerous times (multiple instructions at once) to no avail. I'm still new to Assembly coding so using <code>gdb</code> is a bit too advanced for me. </p>
  
  <p>You will notice that I have included a file called <code>debug</code>. It allows me to look at registers and the stack (that's why there's a <code>dumpstack</code> instruction.) That was provided by my professor and it did help some but obviously not enough (or maybe I am just missing something).</p>
  
  <p><strong>Here's the <code>.cpp</code>:</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  
  using namespace std;
  
  extern "C" double ComputeElectricity();
  
  int main()
  {
      cout &lt;&lt; "Welcome to electric circuit processing by Chris Tarazi." &lt;&lt; endl;
      double returnValue = ComputeElectricity();
      cout &lt;&lt; "The driver received this number: " &lt;&lt; returnValue &lt;&lt; endl; 
      return 0;
  }
  </code></pre>
  
  <p><strong>And here's the <code>ASM</code> code:</strong></p>
  
  <pre><code>%include "debug.inc"
  extern printf
  extern scanf
  global ComputeElectricity
  
  ;---------------------------------Declare variables-------------------------------------------
  
  segment .data
  
  greet db "This progam will help you analyze direct current circuits configured in parallel.", 10, 0
  voltage db "Please enter the voltage of the entire circuit in volts: ", 0
  first db "Enter the power consumption of device 1 (watts): ", 0
  second db "Enter the power consumption of device 2 (watts): ", 0
  third db "Enter the power consumption of device 3 (watts): ", 0
  fourth db "Enter the power consumption of device 4 (watts): ", 0
  thankyou db "Thank you. The computations have completed with the following results.", 10, 0
  circuitV db "Curcuit total voltage: %1.18lf v", 10, 0
  deviceNum db "Device number:                1                    2                    3                    4", 10, 0
  power db "Power (watts): %1.18lf %1.18lf %1.18lf %1.18lf", 10, 0
  current db "Current (amps): %1.18lf %1.18lf %1.18lf %1.18lf", 10, 0
  totalCurrent db "Total current in the circuit is %1.18lf amps.", 10, 0
  totalPower db "Total power in the circuit is %1.18lf watts.", 10, 0
  
  bye db "The analyzer program will now return total power to the driver.", 10, 0
  
  string db "%s", 0
  floatfmt db "%lf", 0
  fourfloat db "%1.18lf %1.18lf %1.18lf %1.18lf", 0
  
  ;---------------------------------Begin segment of executable code------------------------------
  
  segment .text
  
  dumpstack 20, 10, 10
  
  ComputeElectricity:
  
  ;dumpstack 30, 10, 10
  
  ;---------------------------------Output greet message------------------------------------------
  
      mov qword rax, 0
      mov rdi, string 
      mov rsi, greet
      call printf
  
  ;---------------------------------Prompt for voltage--------------------------------------------
  
      mov qword rax, 0
      mov rdi, string
      mov rsi, voltage
      call printf
  
  ;---------------------------------Get  voltage--------------------------------------------------
  
      push qword 0
      mov qword rax, 0
      mov rdi, floatfmt
      mov rsi, rsp
      call scanf
      vbroadcastsd ymm15, [rsp]
      pop rax
  
  ;---------------------------------Prompt for watts 1--------------------------------------------
  
      mov qword rax, 0
      mov rdi, string
      mov rsi, first
      call printf
  
  ;---------------------------------Get watts 1---------------------------------------------------
  
      push qword 0
      mov qword rax, 0
      mov rdi, floatfmt
      mov rsi, rsp
      call scanf
  
  ;---------------------------------Prompt for watts 2--------------------------------------------
  
      mov qword rax, 0
      mov rdi, string
      mov rsi, second         
      call printf 
  
  ;---------------------------------Get watts 2---------------------------------------------------
  
      push qword 0
      mov qword rax, 0
      mov rdi, floatfmt
      mov rsi, rsp
      call scanf
  
  ;---------------------------------Prompt for watts 3--------------------------------------------
  
      mov qword rax, 0
      mov rdi, string
      mov rsi, third      
      call printf 
  
  ;---------------------------------Get watts 3---------------------------------------------------
  
      push qword 0
      mov qword rax, 0
      mov rdi, floatfmt
      mov rsi, rsp
      call scanf
  
  ;---------------------------------Prompt for watts 4--------------------------------------------
  
      mov qword rax, 0
      mov rdi, string
      mov rsi, fourth 
      call printf 
  
  ;---------------------------------Get watts 4---------------------------------------------------
  
      push qword 0
      mov qword rax, 0
      mov rdi, floatfmt
      mov rsi, rsp
      call scanf
  
      ;dumpstack 50, 10, 10
  
  ;---------------------------------Move data into correct registers------------------------------
  
      vmovupd ymm14, [rsp]                ; move all 4 numbers from the stack to ymm14
  
      pop rax
      pop rax
      pop rax
      pop rax
  
      ;dumpstack 55, 10, 10       
  
      vextractf128 xmm10, ymm14, 0        ; get lower half
      vextractf128 xmm11, ymm14, 1        ; get upper half
  
  ;---------------------------------Move data into low xmm registers------------------------------
  
      movsd xmm1, xmm11                   ; move ymm[128-191] (3rd value) into xmm1
      movhlps xmm0, xmm11                 ; move from highest value from xmm11 to xmm0
  
      movsd xmm3, xmm10
      movhlps xmm2, xmm10
  
      ;showymmregisters 999
  
  ;---------------------------------Output results-------------------------------------------------
  
      ;dumpstack 60, 10, 10
  
      mov rax, 4
      mov rdi, fourfloat
      push qword 0
      call printf
      pop rax
  
  ret
  </code></pre>