chart = {
let w = -250;
let h = 500;
let x_position = 925;
let y_position = 250;
let rsp_position = 50;
let count = 0;
var myArray1 = [];
var myArray2 = [];
var myArray3 = [];
let count3 = 0;
let myFlag = true;
var svg = d3.select(DOM.svg(w, h))
.attr("width", width)
.attr("height", height);
svg
.append("rect")
.attr("x", x_position)
.attr("y", 50)
.attr("width", 120)
.attr("height", 180)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
var rsp = svg
.append("g")
.attr("transform", "translate(" + x_position + ", 50)");
rsp
.append("rect")
.attr("width", 120)
.attr("height", 30)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
rsp
.append("text")
.text("%rbp")
.attr("y", 15)
.attr("x", 58)
.attr("alignment-baseline", "middle")
.attr("text-anchor", "middle")
.style("font-family", "consolas");
var label1 = svg
.append("g")
.attr("transform", "translate(0, 50)");
label1
.append("text")
.text("Higher Addresses")
.attr("y", 15)
.attr("x", x_position-100)
.style("font-size", "10px")
.style("font-family", "consolas");
var label2 = svg
.append("g")
.attr("transform", "translate(0, 202)");
label2
.append("text")
.text("Lower Addresses")
.attr("y", 15)
.attr("x", x_position-93)
.style("font-size", "10px")
.style("font-family", "consolas");
var code1 = svg
.append("g")
.attr("transform", "translate(0, 50)");
code1
.append("text")
.text("int add(int x, int y) {")
.attr("y", 60)
.attr("x", 550)
.style("font-family", "consolas");
var code2 = svg
.append("g")
.attr("transform", "translate(0, 50)");
code2
.append("text")
.text("int z = x + y;")
.attr("y", 90)
.attr("x", 575)
.style("font-family", "consolas");
var code3 = svg
.append("g")
.attr("transform", "translate(0, 50)");
code3
.append("text")
.text("return z; }")
.attr("y", 120)
.attr("x", 575)
.style("font-family", "consolas");
var explanation = svg
.append("g")
.attr("transform", "translate(0, 50)");
explanation
.append("text")
.text("Explanation:")
.attr("font-weight", 1000)
.attr("y", 0)
.attr("x", 0)
.style("font-size", "25px")
.style("font-family", "consolas")
.style("fill", "#990099");
var text1 = svg
.append("g")
.attr("transform", "translate(0, 50)");
text1
.append("text")
.text("In this section, we look at how the stack ")
.attr("y", 35)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text1
.append("text")
.text("functions by going through a sample code.")
.attr("y", 60)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text1
.append("text")
.text("The program begins by adding %rbp, a general-purpose")
.attr("y", 85)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text1
.append("text")
.text("register that indicates the 'bottom' of the stack.")
.attr("y", 110)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text1
.append("text")
.text("Note: the stack grows downwards!")
.attr("y", 150)
.attr("x", 25)
.style("font-size", "15px")
.style("font-family", "consolas")
.style("font-style", "italic");
var text2 = svg
.append("g")
.attr("transform", "translate(0, 50)");
text2
.append("text")
.text("When you call a function, the manner")
.attr("y", 35)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("and use of the registers follows a very specific")
.attr("y", 60)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("convention, dictating where function parameters")
.attr("y", 85)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("and the return value should go. There are ")
.attr("y", 110)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("16 general purpose registers used by the machine")
.attr("y", 135)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("to manipulate data. Out of the 16, the following")
.attr("y", 160)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("registers are used in the following order for")
.attr("y", 185)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("parameters and local variables:")
.attr("y", 210)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("%rdi %rsi")
.attr("font-weight", 1000)
.attr("y", 250)
.attr("x", 25)
.style("font-size", "17px")
.style("font-family", "consolas");
text2
.append("text")
.text("%rdx %rcx %r8 %r9")
.attr("font-weight", 1000)
.attr("y", 250)
.attr("x", 115)
.style("font-size", "17px")
.style("font-family", "consolas")
.style("opacity", 0.5);
var text3 = svg
.append("g")
.attr("transform", "translate(0 , 50)");
text3
.append("text")
.text("The third parameter - or in this case local")
.attr("y", 35)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text3
.append("text")
.text("variable z - gets put into the next available")
.attr("y", 65)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text3
.append("text")
.text("register and pushed onto the stack.")
.attr("y", 90)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text3
.append("text")
.text("%rdi %rsi")
.attr("font-weight", 1000)
.attr("y", 125)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas")
.style("opacity", 0.5);
text3
.append("text")
.text("%rdx")
.attr("font-weight", 1000)
.attr("y", 125)
.attr("x", 120)
.style("font-size", "18px")
.style("font-family", "consolas");
text3
.append("text")
.text("%rcx %r8 %r9")
.attr("font-weight", 1000)
.attr("y", 125)
.attr("x", 165)
.style("font-size", "17px")
.style("font-family", "consolas")
.style("opacity", 0.5);
var text4 = svg
.append("g")
.attr("transform", "translate(0, 50)");
text4
.append("text")
.text("Then the return address is stored in")
.attr("y", 35)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text4
.append("text")
.text("its special register, %rax, and pushed")
.attr("y", 60)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text4
.append("text")
.text("onto the stack.")
.attr("y", 85)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
var text5 = svg
.append("g")
.attr("transform", "translate(0, 50)");
text5
.append("text")
.text("Lastly, we push the register %rsp.")
.attr("y", 35)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text5
.append("text")
.text("%rsp is commonly referred to as ")
.attr("y", 60)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text5
.append("text")
.text("the stack pointer, a pointer to")
.attr("y", 85)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
text5
.append("text")
.text("the topmost element in the stack.")
.attr("y", 110)
.attr("x", 25)
.style("font-size", "18px")
.style("font-family", "consolas");
myArray2.push(code1, code2, code3);
myArray3.push(text1, text2, text3, text4, text5);
myArray3.forEach(function(d) {
if(myArray3.indexOf(d) == count) {
d
.style("opacity", 1);
} else {
d
.style("opacity", 0);
}
});
function addingElements () {
if(count == 0) {
var stack_element1 = svg
.append("g")
.attr("transform", "translate(" + x_position + ", 300)");
var stack_element2 = svg
.append("g")
.attr("transform", "translate(" + x_position + ", 300)");
myArray2.forEach(function(d) {
if(myArray2.indexOf(d) == 0) {
d
.attr("font-weight", 600)
.style("opacity", 1)
.style("font-style", "italic")
;
} else {
d
.attr("font-weight", 0)
.style("opacity", 0.25)
.style("font-style", "normal");
}
});
stack_element1
.append("rect")
.attr("width", 120)
.attr("height", 30)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
stack_element1
.append("text")
.text("%rsi: y's val")
.attr("y", 15)
.attr("x", 60)
.attr("alignment-baseline", "middle")
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("font-family", "consolas");
stack_element1
.style("opacity", 0)
.transition()
.delay(500)
.attr("transform", "translate(" + x_position + ", " + 110 + ")")
.style("opacity", 1)
.duration(2500);
stack_element2
.append("rect")
.attr("width", 120)
.attr("height", 30)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
stack_element2
.append("text")
.text("%rdi: x's val")
.attr("y", 15)
.attr("x", 60)
.attr("alignment-baseline", "middle")
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("font-family", "consolas");
stack_element2
.style("opacity", 0)
.transition()
.attr("transform", "translate(" + x_position + ", " + 80 + ")")
.style("opacity", 1)
.duration(2500);
count += 2;
count3 += 1;
myArray1.push(stack_element1, stack_element2);
} else {
myArray2.forEach(function(d) {
if(myArray2.indexOf(d) == (count - 1) ) {
d
.attr("font-weight", 600)
.style("opacity", 1)
.style("font-style", "italic");
} else {
d
.attr("font-weight", 0)
.style("opacity", 0.25)
.style("font-style", "normal");
}
});
var stack_element = svg
.append("g")
.attr("transform", "translate(" + x_position + ", 300)");
stack_element
.append("rect")
.attr("width", 120)
.attr("height", 30)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
if(count == 2) {
stack_element
.append("text")
.text("%rdx: local var z")
.attr("y", 15)
.attr("x", 60)
.attr("alignment-baseline", "middle")
.attr("text-anchor", "middle")
.style("font-size", "11.5px")
.style("font-family", "consolas");
stack_element
.style("opacity", 0)
.transition()
.attr("transform", "translate(" + x_position + ", " + 140 + ")")
.style("opacity", 1)
.duration(2500);
} else if (count == 3) {
stack_element
.append("text")
.text("%rax: ret")
.attr("y", 15)
.attr("x", 60)
.attr("alignment-baseline", "middle")
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("font-family", "consolas");
stack_element
.style("opacity", 0)
.transition()
.attr("transform", "translate(" + x_position + ", " + 170 + ")")
.style("opacity", 1)
.duration(2500)
;
}
myArray1.push(stack_element);
count += 1;
count3 += 1;
}
myArray3.forEach(function(a) {
if(myArray3.indexOf(a) == count3) {
a
.transition()
.duration(1500)
.style("opacity", 1);
} else {
a
.transition()
.duration(500)
.style("opacity", 0);
}
});
}
d3.select("#step").on("click", function() {
if(count <= 3){
addingElements();
} else if (count > 3) {
count = 5;
count3 = 4;
y_position = 250;
myArray2.forEach(function(d) {
d
.transition()
.attr("font-weight", 0)
.style("opacity", 1)
.style("font-style", "normal");
});
myArray3.forEach(function(a) {
if(myArray3.indexOf(a) == count3 ) {
a
.transition()
.duration(1500)
.style("opacity", 1);
} else {
a
.transition()
.duration(500)
.style("opacity", 0);
}
});
if(myFlag){
myFlag = false;
var stack_element_final = svg
.append("g")
.attr("transform", "translate(" + x_position + ", 300)");
stack_element_final
.append("rect")
.attr("width", 120)
.attr("height", 30)
.attr("stroke", "black")
.attr("stroke-width", 3)
.attr("fill", "none");
stack_element_final
.append("text")
.text("%rsp")
.attr("y", 15)
.attr("x", 60)
.attr("alignment-baseline", "middle")
.attr("text-anchor", "middle")
.style("font-family", "consolas");
stack_element_final
.style("opacity", 0)
.transition()
.duration(2500)
.attr("transform", "translate(" + x_position + ", " + 200 + ")")
.style("opacity", 1);
myArray1.push(stack_element_final);
}
}
});
function myReset (){
count = 0;
count3 = 0;
myFlag = true;
rsp_position = 50;
myArray1.forEach(function(d) {
d
.transition()
.style("opacity", 0)
});
myArray1 = [];
myArray2.forEach(function(d) {
d
.transition()
.attr("font-weight", 0)
.style("opacity", 1)
.style("font-style", "normal");
});
myArray3.forEach(function(a) {
if(myArray3.indexOf(a) == count3 ) {
a
.transition()
.duration(1500)
.style("opacity", 1);
} else {
a
.transition()
.duration(500)
.style("opacity", 0);
}
});
rsp
.transition()
.duration(2500)
.attr("transform", "translate(" + x_position + ", " + rsp_position + ")");
};
d3.select("#back").on("click", function() {
if (count < 3) {
myReset();
} else {
var last_element = myArray1.pop();
var temp = 4;
if(count == 5) {
myFlag = true;
temp -= 1;
} else if(count == 4) {
temp -= 2;
} else if (count == 3) {
temp -= 3;
}
last_element
.transition()
.style("opacity", 0);
myArray2.forEach(function(d) {
if(myArray2.indexOf(d) == (temp - 1)) {
d
.attr("font-weight", 600)
.style("opacity", 1)
.style("font-style", "italic");
} else {
d
.attr("font-weight", 0)
.style("opacity", 0.25)
.style("font-style", "normal");
}
});
count -= 1;
count3 = count - 1;
myArray3.forEach(function(a) {
if(myArray3.indexOf(a) == (temp) ) {
a
.transition()
.duration(1500)
.style("opacity", 1);
} else {
a
.transition()
.duration(500)
.style("opacity", 0);
}
});
}
});
d3.select("#reset").on("click", myReset);
return svg.node();
}