-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcalculator-x8664.c
More file actions
131 lines (123 loc) · 4.27 KB
/
Copy pathcalculator-x8664.c
File metadata and controls
131 lines (123 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Fungsi untuk menampilkan cara penggunaan kalkulator
void show_help() {
printf("Penggunaan: ./calculator <input> <operator> <input> ...\n");
printf("Operator yang tersedia:\n");
printf(" + : Penjumlahan\n");
printf(" - : Pengurangan\n");
printf(" x : Perkalian\n");
printf(" / : Pembagian\n");
printf("Contoh:\n");
printf(" ./calculator 1 + 1\n");
printf(" ./calculator 2 + 2 + 2\n");
printf(" ./calculator 10 x 2\n");
printf(" ./calculator 1 - 1 + 20 x 2\n");
}
// Fungsi untuk menghitung operasi aritmatika
long calculate(long num1, char op, long num2) {
long result;
#if defined(__x86_64__) // Untuk arsitektur x86_64 atau AMD64
switch(op) {
case '+':
__asm__ (
"addq %1, %0;" // result = num1 + num2
: "=r" (result)
: "r" (num2), "0" (num1)
);
break;
case '-':
__asm__ (
"subq %1, %0;" // result = num1 - num2
: "=r" (result)
: "r" (num2), "0" (num1)
);
break;
case 'x': // Perkalian
__asm__ (
"imulq %1, %0;" // result = num1 * num2
: "=r" (result)
: "r" (num2), "0" (num1)
);
break;
case '/': // Pembagian
if (num2 == 0) {
printf("Error: Pembagian dengan nol tidak diperbolehkan!\n");
exit(1);
}
__asm__ (
"cqto;" // Convert to quadword untuk pembagian
"idivq %2;" // result = num1 / num2
: "=a" (result)
: "d" (num1), "r" (num2)
);
break;
default:
printf("Operator tidak dikenal!\n");
exit(1);
}
#elif defined(__i386__) // Untuk arsitektur x86 (32-bit)
switch(op) {
case '+':
__asm__ (
"addl %1, %0;" // result = num1 + num2
: "=r" (result)
: "r" (num2), "0" (num1)
);
break;
case '-':
__asm__ (
"subl %1, %0;" // result = num1 - num2
: "=r" (result)
: "r" (num2), "0" (num1)
);
break;
case 'x': // Perkalian
__asm__ (
"imull %1, %0;" // result = num1 * num2
: "=r" (result)
: "r" (num2), "0" (num1)
);
break;
case '/': // Pembagian
if (num2 == 0) {
printf("Error: Pembagian dengan nol tidak diperbolehkan!\n");
exit(1);
}
__asm__ (
"cltd;" // Convert to doubleword untuk pembagian
"idivl %2;" // result = num1 / num2
: "=a" (result)
: "d" (num1), "r" (num2)
);
break;
default:
printf("Operator tidak dikenal!\n");
exit(1);
}
#else
printf("Arsitektur tidak didukung! Hanya mendukung x86 dan x86_64.\n");
exit(1);
#endif
return result;
}
int main(int argc, char *argv[]) {
// Mengecek apakah --help diminta
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
show_help();
return 0;
}
if (argc < 4) {
printf("Error: Format salah. Gunakan ./calculator --help untuk bantuan.\n");
return 1;
}
long result = atol(argv[1]); // Mengonversi input pertama menjadi long
for (int i = 2; i < argc; i += 2) {
char operator = argv[i][0]; // Mengambil operator (+, -, x, /)
long next_num = atol(argv[i + 1]); // Mengonversi angka berikutnya menjadi long
result = calculate(result, operator, next_num); // Menjalankan kalkulasi
}
printf("Hasil: %ld\n", result);
return 0;
}