Segmentation fault on printf - NASM 64bit Linux












0















I trying to input four floats using scanf, store them onto the stack, and then use vmovupd 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 printf.



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 gdb is a bit too advanced for me.



You will notice that I have included a file called debug. It allows me to look at registers and the stack (that's why there's a dumpstack instruction.) That was provided by my professor and it did help some but obviously not enough (or maybe I am just missing something).



Here's the .cpp:



#include <iostream>

using namespace std;

extern "C" double ComputeElectricity();

int main()
{
cout << "Welcome to electric circuit processing by Chris Tarazi." << endl;

double returnValue = ComputeElectricity();

cout << "The driver received this number: " << returnValue << endl;

return 0;
}


And here's the ASM 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









share|improve this question

























  • Why not simply write a 'C' program that calls printf, generate the assembly listing, and learn from that listing how the compiler does it?

    – PaulMcKenzie
    Sep 5 '14 at 20:58











  • @PaulMcKenzie I generated this if you could look at it and point me in the right direction. I still can't figure out why it's happening

    – ctzdev
    Sep 5 '14 at 21:27








  • 1





    I am baffled why people keep suggesting studying compiler generated code. Reverse engineering is pretty much the hardest most complicated task, and you can quickly draw wrong conclusions especially from compiler generated code. Instead, read the relevant documentation (ABI and instruction set) and use a debugger.

    – Jester
    Sep 5 '14 at 21:50
















0















I trying to input four floats using scanf, store them onto the stack, and then use vmovupd 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 printf.



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 gdb is a bit too advanced for me.



You will notice that I have included a file called debug. It allows me to look at registers and the stack (that's why there's a dumpstack instruction.) That was provided by my professor and it did help some but obviously not enough (or maybe I am just missing something).



Here's the .cpp:



#include <iostream>

using namespace std;

extern "C" double ComputeElectricity();

int main()
{
cout << "Welcome to electric circuit processing by Chris Tarazi." << endl;

double returnValue = ComputeElectricity();

cout << "The driver received this number: " << returnValue << endl;

return 0;
}


And here's the ASM 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









share|improve this question

























  • Why not simply write a 'C' program that calls printf, generate the assembly listing, and learn from that listing how the compiler does it?

    – PaulMcKenzie
    Sep 5 '14 at 20:58











  • @PaulMcKenzie I generated this if you could look at it and point me in the right direction. I still can't figure out why it's happening

    – ctzdev
    Sep 5 '14 at 21:27








  • 1





    I am baffled why people keep suggesting studying compiler generated code. Reverse engineering is pretty much the hardest most complicated task, and you can quickly draw wrong conclusions especially from compiler generated code. Instead, read the relevant documentation (ABI and instruction set) and use a debugger.

    – Jester
    Sep 5 '14 at 21:50














0












0








0


1






I trying to input four floats using scanf, store them onto the stack, and then use vmovupd 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 printf.



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 gdb is a bit too advanced for me.



You will notice that I have included a file called debug. It allows me to look at registers and the stack (that's why there's a dumpstack instruction.) That was provided by my professor and it did help some but obviously not enough (or maybe I am just missing something).



Here's the .cpp:



#include <iostream>

using namespace std;

extern "C" double ComputeElectricity();

int main()
{
cout << "Welcome to electric circuit processing by Chris Tarazi." << endl;

double returnValue = ComputeElectricity();

cout << "The driver received this number: " << returnValue << endl;

return 0;
}


And here's the ASM 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









share|improve this question
















I trying to input four floats using scanf, store them onto the stack, and then use vmovupd 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 printf.



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 gdb is a bit too advanced for me.



You will notice that I have included a file called debug. It allows me to look at registers and the stack (that's why there's a dumpstack instruction.) That was provided by my professor and it did help some but obviously not enough (or maybe I am just missing something).



Here's the .cpp:



#include <iostream>

using namespace std;

extern "C" double ComputeElectricity();

int main()
{
cout << "Welcome to electric circuit processing by Chris Tarazi." << endl;

double returnValue = ComputeElectricity();

cout << "The driver received this number: " << returnValue << endl;

return 0;
}


And here's the ASM 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






c++ linux assembly nasm






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 5 '14 at 22:24







ctzdev

















asked Sep 5 '14 at 20:53









ctzdevctzdev

4762819




4762819













  • Why not simply write a 'C' program that calls printf, generate the assembly listing, and learn from that listing how the compiler does it?

    – PaulMcKenzie
    Sep 5 '14 at 20:58











  • @PaulMcKenzie I generated this if you could look at it and point me in the right direction. I still can't figure out why it's happening

    – ctzdev
    Sep 5 '14 at 21:27








  • 1





    I am baffled why people keep suggesting studying compiler generated code. Reverse engineering is pretty much the hardest most complicated task, and you can quickly draw wrong conclusions especially from compiler generated code. Instead, read the relevant documentation (ABI and instruction set) and use a debugger.

    – Jester
    Sep 5 '14 at 21:50



















  • Why not simply write a 'C' program that calls printf, generate the assembly listing, and learn from that listing how the compiler does it?

    – PaulMcKenzie
    Sep 5 '14 at 20:58











  • @PaulMcKenzie I generated this if you could look at it and point me in the right direction. I still can't figure out why it's happening

    – ctzdev
    Sep 5 '14 at 21:27








  • 1





    I am baffled why people keep suggesting studying compiler generated code. Reverse engineering is pretty much the hardest most complicated task, and you can quickly draw wrong conclusions especially from compiler generated code. Instead, read the relevant documentation (ABI and instruction set) and use a debugger.

    – Jester
    Sep 5 '14 at 21:50

















Why not simply write a 'C' program that calls printf, generate the assembly listing, and learn from that listing how the compiler does it?

– PaulMcKenzie
Sep 5 '14 at 20:58





Why not simply write a 'C' program that calls printf, generate the assembly listing, and learn from that listing how the compiler does it?

– PaulMcKenzie
Sep 5 '14 at 20:58













@PaulMcKenzie I generated this if you could look at it and point me in the right direction. I still can't figure out why it's happening

– ctzdev
Sep 5 '14 at 21:27







@PaulMcKenzie I generated this if you could look at it and point me in the right direction. I still can't figure out why it's happening

– ctzdev
Sep 5 '14 at 21:27






1




1





I am baffled why people keep suggesting studying compiler generated code. Reverse engineering is pretty much the hardest most complicated task, and you can quickly draw wrong conclusions especially from compiler generated code. Instead, read the relevant documentation (ABI and instruction set) and use a debugger.

– Jester
Sep 5 '14 at 21:50





I am baffled why people keep suggesting studying compiler generated code. Reverse engineering is pretty much the hardest most complicated task, and you can quickly draw wrong conclusions especially from compiler generated code. Instead, read the relevant documentation (ABI and instruction set) and use a debugger.

– Jester
Sep 5 '14 at 21:50












1 Answer
1






active

oldest

votes


















3














The problem is with your stack usage.
First, the ABI docs mandate rsp be kept 16 byte aligned. Since a call will put a 8 byte return address on the stack, you need to adjust rsp by a multiple of 16 plus 8. This is the immediate cause of the segfault, because printf will use aligned SSE instructions which will fault for unaligned addresses.



If you fix that, your stack is still unbalanced, because you keep pushing values but never pop them. It's hard to understand what you want to do with the stack.



The usual way is to allocate space for the locals in the beginning of your function (the prologue) and free this at the end (epilogue). As discussed above, this amount should be a multiple of 16 plus 8.






share|improve this answer
























  • I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

    – ctzdev
    Sep 5 '14 at 21:58








  • 1





    align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

    – Jester
    Sep 5 '14 at 22:17











  • Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

    – ctzdev
    Sep 5 '14 at 22:23













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25693827%2fsegmentation-fault-on-printf-nasm-64bit-linux%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














The problem is with your stack usage.
First, the ABI docs mandate rsp be kept 16 byte aligned. Since a call will put a 8 byte return address on the stack, you need to adjust rsp by a multiple of 16 plus 8. This is the immediate cause of the segfault, because printf will use aligned SSE instructions which will fault for unaligned addresses.



If you fix that, your stack is still unbalanced, because you keep pushing values but never pop them. It's hard to understand what you want to do with the stack.



The usual way is to allocate space for the locals in the beginning of your function (the prologue) and free this at the end (epilogue). As discussed above, this amount should be a multiple of 16 plus 8.






share|improve this answer
























  • I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

    – ctzdev
    Sep 5 '14 at 21:58








  • 1





    align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

    – Jester
    Sep 5 '14 at 22:17











  • Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

    – ctzdev
    Sep 5 '14 at 22:23


















3














The problem is with your stack usage.
First, the ABI docs mandate rsp be kept 16 byte aligned. Since a call will put a 8 byte return address on the stack, you need to adjust rsp by a multiple of 16 plus 8. This is the immediate cause of the segfault, because printf will use aligned SSE instructions which will fault for unaligned addresses.



If you fix that, your stack is still unbalanced, because you keep pushing values but never pop them. It's hard to understand what you want to do with the stack.



The usual way is to allocate space for the locals in the beginning of your function (the prologue) and free this at the end (epilogue). As discussed above, this amount should be a multiple of 16 plus 8.






share|improve this answer
























  • I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

    – ctzdev
    Sep 5 '14 at 21:58








  • 1





    align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

    – Jester
    Sep 5 '14 at 22:17











  • Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

    – ctzdev
    Sep 5 '14 at 22:23
















3












3








3







The problem is with your stack usage.
First, the ABI docs mandate rsp be kept 16 byte aligned. Since a call will put a 8 byte return address on the stack, you need to adjust rsp by a multiple of 16 plus 8. This is the immediate cause of the segfault, because printf will use aligned SSE instructions which will fault for unaligned addresses.



If you fix that, your stack is still unbalanced, because you keep pushing values but never pop them. It's hard to understand what you want to do with the stack.



The usual way is to allocate space for the locals in the beginning of your function (the prologue) and free this at the end (epilogue). As discussed above, this amount should be a multiple of 16 plus 8.






share|improve this answer













The problem is with your stack usage.
First, the ABI docs mandate rsp be kept 16 byte aligned. Since a call will put a 8 byte return address on the stack, you need to adjust rsp by a multiple of 16 plus 8. This is the immediate cause of the segfault, because printf will use aligned SSE instructions which will fault for unaligned addresses.



If you fix that, your stack is still unbalanced, because you keep pushing values but never pop them. It's hard to understand what you want to do with the stack.



The usual way is to allocate space for the locals in the beginning of your function (the prologue) and free this at the end (epilogue). As discussed above, this amount should be a multiple of 16 plus 8.







share|improve this answer












share|improve this answer



share|improve this answer










answered Sep 5 '14 at 21:49









JesterJester

46.7k34682




46.7k34682













  • I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

    – ctzdev
    Sep 5 '14 at 21:58








  • 1





    align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

    – Jester
    Sep 5 '14 at 22:17











  • Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

    – ctzdev
    Sep 5 '14 at 22:23





















  • I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

    – ctzdev
    Sep 5 '14 at 21:58








  • 1





    align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

    – Jester
    Sep 5 '14 at 22:17











  • Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

    – ctzdev
    Sep 5 '14 at 22:23



















I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

– ctzdev
Sep 5 '14 at 21:58







I should do align 16 in the prologue then adjust rsp by a multiple of 16 plus 8? I understand the aligning part but not the adjusting. Could you elaborate on that please? Also, what I did with the stack was that I put 4 values onto the stack and had vmovupd pick up those 4 values and place them into ymm14. From there I'm not sure what to do.

– ctzdev
Sep 5 '14 at 21:58






1




1





align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

– Jester
Sep 5 '14 at 22:17





align is for aligning code and data at assembly/link time. What I meant was keeping rsp aligned, you achieve that by only adjusting it in multiples of 16 plus 8. You have put things onto the stack, but not removed them.

– Jester
Sep 5 '14 at 22:17













Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

– ctzdev
Sep 5 '14 at 22:23







Nevermind. Looks like my professor's code was causing problems with the registers. I did however pop 4 times after moving the 4 values off the stack. Then added push qword 0 before printf then pop rax after printf.

– ctzdev
Sep 5 '14 at 22:23




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25693827%2fsegmentation-fault-on-printf-nasm-64bit-linux%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

How to fix TextFormField cause rebuild widget in Flutter