Rev 7406 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
7411 | pavelyakov | 1 | // version 0.03 |
7405 | pavelyakov | 2 | // Author: Pavel Iakovlev |
7406 | pavelyakov | 3 | // http://shell-storm.org/online/Online-Assembler-and-Disassembler/?inst=&arch=arm#assembly - online compiler (Little endian:) |
7405 | pavelyakov | 4 | |
5 | |||
6 | #pragma option OST |
||
7 | #pragma option ON |
||
8 | #pragma option cri- |
||
9 | #pragma option -CPA |
||
10 | #initallvar 0 |
||
11 | #jumptomain FALSE |
||
12 | |||
13 | #startaddress 0x10000 |
||
14 | |||
15 | #code32 TRUE |
||
16 | |||
17 | char os_name[8] = {'M','E','N','U','E','T','0','1'}; |
||
18 | dword os_version = 0x00000001; |
||
19 | dword start_addr = #main; |
||
20 | dword final_addr = #______STOP______+32; |
||
21 | dword alloc_mem = 20000; |
||
22 | dword x86esp_reg = 20000; |
||
23 | dword I_Param = #param; |
||
24 | dword I_Path = #program_path; |
||
25 | char param[4096] ={0}; |
||
26 | char program_path[4096] = {0}; |
||
27 | |||
7406 | pavelyakov | 28 | // test opcode arm, compiler (http://shell-storm.org/online/Online-Assembler-and-Disassembler/?inst=mov+r0%2C1%0D%0Amov+r5%2C2%0D%0Amov+r2%2C+r0%2C+lsl+r5&arch=arm#assembly) (Little endian:) |
7405 | pavelyakov | 29 | |
7411 | pavelyakov | 30 | dword test_bytecode = "\x04\x10\x5f\xe5\x7b\x00\x00\x00"; |
7406 | pavelyakov | 31 | |
32 | // -------------------- |
||
33 | |||
7405 | pavelyakov | 34 | struct _reg // registers arm |
35 | { |
||
36 | dword r0; |
||
37 | dword r1; |
||
38 | dword r2; |
||
39 | dword r3; |
||
40 | dword r4; |
||
41 | dword r5; |
||
42 | dword r6; |
||
43 | dword r7; |
||
44 | dword r8; |
||
45 | dword r9; |
||
46 | dword r10; |
||
47 | dword r11; |
||
48 | dword r12; // (Intra-Procedure-call scratch register) |
||
49 | dword r13; // (Stack Pointer) |
||
50 | dword r14; // (Link Register) |
||
51 | dword r15; // PC (Program Counter) |
||
52 | }; |
||
53 | |||
54 | _reg reg = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // clear and init registers |
||
55 | dword REG = #reg; |
||
56 | |||
57 | struct _flags |
||
58 | { |
||
59 | byte negative; |
||
60 | byte zero; |
||
61 | byte carry; |
||
62 | byte overflow; |
||
63 | }; |
||
64 | |||
65 | _flags flags = {0,0,0,0}; // clear and init flags |
||
66 | |||
67 | struct _mode |
||
68 | { |
||
69 | byte User; |
||
70 | byte FastInterrupt; |
||
71 | byte Interrupt; |
||
72 | byte Supervisor; |
||
73 | }; |
||
74 | |||
75 | _mode mode = {0,0,0,0}; // processor mode |
||
76 | |||
77 | struct _mask |
||
78 | { |
||
79 | byte IRQ; |
||
80 | byte FIRQ; |
||
81 | }; |
||
82 | |||
83 | _mask mask = {0,0}; // processor mask |
||
84 | |||
85 | void main() |
||
86 | { |
||
87 | |||
7411 | pavelyakov | 88 | callOpcode(#test_bytecode,1); |
7405 | pavelyakov | 89 | |
90 | EAX = -1; |
||
91 | $int 0x40; |
||
92 | } |
||
93 | |||
94 | dword callOpcode(dword binary, lengthInstruction) |
||
95 | { |
||
96 | dword command = 0; |
||
97 | dword PC = 0; |
||
98 | byte flag = 0; |
||
99 | byte pMask = 0; |
||
100 | byte pMode = 0; |
||
101 | while(lengthInstruction) |
||
102 | { |
||
7406 | pavelyakov | 103 | //PC = reg.r15 >> 2 & 0xFFFFFF; |
7405 | pavelyakov | 104 | flag = reg.r15 >> 28; |
105 | pMask = reg.r15 >> 26; |
||
106 | |||
107 | flags.negative = flag & 0x8; |
||
108 | flags.zero = flag & 0x4; |
||
109 | flags.carry = flag & 0x2; |
||
110 | flags.overflow = flag & 0x1; |
||
111 | |||
112 | mask.IRQ = pMask & 0x2; |
||
113 | mask.FIRQ = pMask & 0x1; |
||
114 | |||
115 | switch(reg.r15 & 3) |
||
116 | { |
||
117 | case 0: |
||
118 | DSDWORD[#mode] = 0x000000FF; |
||
119 | break; |
||
120 | case 1: |
||
121 | DSDWORD[#mode] = 0x0000FF00; |
||
122 | break; |
||
123 | case 2: |
||
124 | DSDWORD[#mode] = 0x00FF0000; |
||
125 | break; |
||
126 | case 3: |
||
127 | DSDWORD[#mode] = 0xFF000000; |
||
128 | break; |
||
129 | } |
||
130 | |||
131 | command = DSDWORD[binary + PC]; // generation PC instruction |
||
132 | //EAX = DSDWORD[command >> 28 << 2 + #opcodeExec]; // get opcodeExecition call instruction |
||
133 | //EAX(command); // call opcodeExecition |
||
134 | //IF (command & 0xC000000 == 0) opcodeExec0(command); |
||
7411 | pavelyakov | 135 | if (command & 0x0FFFFFF0 == 0x12FFF10) BranchExchange(command); |
136 | else if (command & 0x0FF00FF0 == 0x1000090) SingleDataSwap(command); |
||
137 | else if (command & 0x0FC000F0 == 0x0000090) Multiply(command); |
||
138 | else if (command & 0x0FC000F0 == 0x0800090) MultiplyLong(command); |
||
139 | else if (command & 0x0C000000 == 0x0000000) DataProcessing(command); |
||
140 | else if (command & 0xE000010 == 0x6000010) ;// undefined |
||
141 | else if (command & 0xC000000 == 0x4000000) SingleDataTransfer(command, binary); |
||
7405 | pavelyakov | 142 | |
143 | PC += 4; // addition 4 for reg15 or PC instruction |
||
7406 | pavelyakov | 144 | //PC <<= 2; |
7405 | pavelyakov | 145 | |
146 | flag = 0; |
||
147 | IF (flags.negative) flag |= 0x8; |
||
148 | IF (flags.zero) flag |= 0x4; |
||
149 | IF (flags.carry) flag |= 0x2; |
||
150 | IF (flags.overflow) flag |= 0x1; |
||
151 | |||
152 | pMask = 0; |
||
153 | IF (mask.IRQ) pMask |= 0x2; |
||
154 | IF (mask.FIRQ) pMask |= 0x1; |
||
155 | |||
7411 | pavelyakov | 156 | if (mode.User) pMode = 0; |
157 | else IF (mode.FastInterrupt) pMode = 1; |
||
158 | else IF (mode.Interrupt) pMode = 2; |
||
159 | else IF (mode.Supervisor) pMode = 3; |
||
7405 | pavelyakov | 160 | |
7406 | pavelyakov | 161 | //reg.r15 = flag << 28 | PC | pMode; |
7405 | pavelyakov | 162 | lengthInstruction--; |
163 | } |
||
164 | } |
||
165 | |||
166 | dword Multiply(dword command) |
||
167 | { |
||
168 | |||
169 | } |
||
170 | |||
171 | dword MultiplyLong(dword command) |
||
172 | { |
||
173 | |||
174 | } |
||
175 | |||
176 | dword SingleDataSwap(dword command) |
||
177 | { |
||
178 | |||
179 | } |
||
180 | |||
181 | dword BranchExchange(dword command) |
||
182 | { |
||
183 | |||
184 | } |
||
185 | |||
7411 | pavelyakov | 186 | dword SingleDataTransfer(dword command, binary) |
187 | { |
||
188 | dword Rd = #reg; |
||
189 | dword Rn = #reg; |
||
190 | dword offset = 0; |
||
191 | |||
192 | Rd += command >> 12 & 0xF << 2; |
||
193 | Rn += command >> 16 & 0xF << 2; |
||
194 | offset = command & 0xFFF; |
||
195 | IF (command >> 16 & 0xF != 15) IF (command & 0x800000 == 0) $neg offset; |
||
196 | |||
197 | IF (command & 0x400000) // byte |
||
198 | { |
||
199 | IF (command >> 16 & 0xF == 15) |
||
200 | { |
||
201 | IF (command & 0x100000) DSDWORD[Rd] = DSBYTE[binary + offset]; |
||
202 | ELSE DSBYTE[binary + offset] = DSDWORD[Rd]; |
||
203 | |||
204 | } |
||
205 | ELSE |
||
206 | { |
||
207 | Rn = DSDWORD[Rn]; |
||
208 | IF (command & 0x2000000 == 0) Rn += offset; |
||
209 | IF (command & 0x100000) DSDWORD[Rd] = DSDWORD[binary + Rn]; |
||
210 | ELSE DSDWORD[binary + Rn] = DSDWORD[Rd]; |
||
211 | } |
||
212 | } |
||
213 | ELSE // dword |
||
214 | { |
||
215 | Rn = DSDWORD[Rn]; |
||
216 | IF (command & 0x2000000 == 0) Rn += offset; |
||
217 | IF (command & 0x100000) DSDWORD[Rd] = DSDWORD[binary + Rn]; |
||
218 | ELSE DSDWORD[binary + Rn] = DSDWORD[Rd]; |
||
219 | } |
||
220 | |||
221 | } |
||
222 | |||
7405 | pavelyakov | 223 | dword DataProcessing(dword command) // Data Processing / PSR Transfer |
224 | { |
||
225 | dword opcode = 0; |
||
226 | dword Rd = #reg; |
||
227 | dword Rn = #reg; |
||
228 | dword operand = 0; |
||
7406 | pavelyakov | 229 | word sdvig = 0; |
230 | word context = 0; |
||
231 | byte typeSdvig = 0; |
||
7405 | pavelyakov | 232 | opcode = command >> 21 & 0xF; |
233 | Rd += command >> 12 & 0xF << 2; |
||
234 | Rn += command >> 16 & 0xF << 2; |
||
7406 | pavelyakov | 235 | context = command & 0xFFF; |
7405 | pavelyakov | 236 | |
7406 | pavelyakov | 237 | IF (command & 0x2000000) operand = context; |
238 | ELSE operand = DSDWORD[context & 1111b << 2 + #reg]; |
||
239 | |||
240 | typeSdvig = context >> 5 & 11b; |
||
241 | IF (context & 10000b) sdvig = DSBYTE[context >> 8 & 1111b << 2 + #reg]; |
||
242 | ELSE sdvig = context >> 7 & 11111b; |
||
243 | |||
244 | switch (typeSdvig) // type sdvig |
||
7405 | pavelyakov | 245 | { |
7406 | pavelyakov | 246 | case 0: // logic left |
247 | operand <<= sdvig; |
||
248 | break; |
||
249 | case 1: // logic right |
||
250 | operand >>= sdvig; |
||
251 | break; |
||
252 | case 2: // arifmetic left |
||
253 | |||
254 | break; |
||
255 | case 3: // arifmetic right |
||
256 | |||
257 | break; |
||
7405 | pavelyakov | 258 | } |
259 | |||
260 | switch (opcode) |
||
261 | { |
||
262 | case 0: // and |
||
263 | DSDWORD[Rd] = DSDWORD[Rn] & operand; |
||
264 | break; |
||
265 | case 1: // eor |
||
266 | DSDWORD[Rd] = DSDWORD[Rn] | operand; |
||
267 | break; |
||
268 | case 2: // sub |
||
269 | DSDWORD[Rd] = DSDWORD[Rn] - operand; |
||
270 | break; |
||
271 | case 3: // rsb |
||
272 | DSDWORD[Rd] = operand - DSDWORD[Rn]; |
||
273 | break; |
||
274 | case 4: // add |
||
275 | DSDWORD[Rd] = DSDWORD[Rn] + operand; |
||
276 | break; |
||
7406 | pavelyakov | 277 | case 5: // adc |
278 | DSDWORD[Rd] = DSDWORD[Rn] + operand; |
||
279 | break; |
||
280 | case 6: // sbc |
||
281 | |||
282 | break; |
||
283 | case 7: // rsc |
||
284 | |||
285 | break; |
||
286 | case 8: // tst |
||
287 | |||
288 | break; |
||
289 | case 9: // teq |
||
290 | |||
291 | break; |
||
292 | case 10: // cmp |
||
293 | |||
294 | break; |
||
295 | case 11: // cmn |
||
296 | |||
297 | break; |
||
298 | case 12: // orr |
||
299 | DSDWORD[Rd] = DSDWORD[Rn] | operand; |
||
300 | break; |
||
301 | case 13: // mov |
||
302 | DSDWORD[Rd] = operand; |
||
303 | break; |
||
304 | case 14: // bic |
||
305 | $not operand; |
||
306 | DSDWORD[Rd] = DSDWORD[Rn] & operand; |
||
307 | break; |
||
308 | case 15: // mvn |
||
309 | DSDWORD[Rd] = DSDWORD[Rn] + operand; |
||
310 | break; |
||
7405 | pavelyakov | 311 | } |
7411 | pavelyakov | 312 | |
7405 | pavelyakov | 313 | } |
314 | |||
315 | |||
316 | |||
317 | ______STOP______:=><=>><>><>><>><>><>><>><>=><=>><> |