summaryrefslogtreecommitdiff
path: root/CSAPP/tmul_asm.c
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:55:07 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:56:55 +0200
commitd98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch)
tree267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /CSAPP/tmul_asm.c
parent869e68986aa8f69af6e7842260a68d1e5c6f796f (diff)
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'CSAPP/tmul_asm.c')
-rw-r--r--CSAPP/tmul_asm.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/CSAPP/tmul_asm.c b/CSAPP/tmul_asm.c
new file mode 100644
index 0000000..e496618
--- /dev/null
+++ b/CSAPP/tmul_asm.c
@@ -0,0 +1,51 @@
+int tmul_bug(long x, long y, long *dest)
+{
+ long result = 0;
+ *dest = x*y;
+ asm("setae %al");
+ return result;
+}
+
+int tmul_ok(long x, long y, long *dest)
+{
+ int result = 0;
+ *dest = x*y;
+ asm("setae %%bl # Set low-order byte\n\t"
+ "movzbl %%bl, %[val] # Zero extend to be res"
+ : [val] "=r" (result) /* Output */
+ : /* No inputs */
+ : "%bl" /* Overwrites */
+ );
+ return result;
+}
+
+int tmul_ok2(long x, long y, long *dest)
+{
+ unsigned char result = 0;
+ *dest = x*y;
+
+ asm("setae %[b] # Set result"
+ : [b] "=r" (result) /* Output */
+ );
+ return (int)result;
+}
+
+int umult_ok(unsigned long x, unsigned long y, unsigned long *dest)
+{
+ /*
+ * GCC's asm choose the register to store asm operands
+ * according to the type/size of the variable
+ */
+ unsigned char result;
+
+ asm("movq %[x],%%rax #Get x\n\t"
+ "mulq %[y] # Unsigned long mult x*y\n\t"
+ "movq %%rax,%[p] #Store low-order 8bytes at dest\n\t"
+ "setae %[b] #Set result"
+ : [p] "=m" (*dest), [b] "=r" (result) /* Outputs */
+ : [x] "r" (x), [y] "r" (y) /* Inputs */
+ : "%rax", "%rdx" /* Overwrites */
+ );
+
+ return (int) result;
+}