Mercurial > repos > tabletprog
comparison modules/x86.tp @ 181:f188723c15b4
Add call instruction to x86 module
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 24 Aug 2013 16:21:42 -0700 |
parents | 270d31c6c4cd |
children | 97f107b9e8d3 |
comparison
equal
deleted
inserted
replaced
180:270d31c6c4cd | 181:f188723c15b4 |
---|---|
8 string <- { regnames get: regnum } | 8 string <- { regnames get: regnum } |
9 rm <- :tail { reg or 0xC0u8 | tail } | 9 rm <- :tail { reg or 0xC0u8 | tail } |
10 validforSize? <- :size { true } | 10 validforSize? <- :size { true } |
11 isInteger? <- { false } | 11 isInteger? <- { false } |
12 register? <- { true } | 12 register? <- { true } |
13 localLabel? <- { false } | 13 label? <- { false } |
14 upper? <- { true } | 14 upper? <- { true } |
15 needsRex? <- { regnum >= 8u8 } | 15 needsRex? <- { regnum >= 8u8 } |
16 rexBitReg <- { | 16 rexBitReg <- { |
17 if: needsRex? { | 17 if: needsRex? { |
18 4u8 | 18 4u8 |
42 validforSize? <- :size { | 42 validforSize? <- :size { |
43 size = byte | 43 size = byte |
44 } | 44 } |
45 isInteger? <- { false } | 45 isInteger? <- { false } |
46 register? <- { true } | 46 register? <- { true } |
47 localLabel? <- { false } | 47 label? <- { false } |
48 upper? <- { true } | 48 upper? <- { true } |
49 needsRex? <- { false } | 49 needsRex? <- { false } |
50 = <- :other { | 50 = <- :other { |
51 (not: (other isInteger?)) && (other register?) && (other upper?) && regnum = (other num) | 51 (not: (other isInteger?)) && (other register?) && (other upper?) && regnum = (other num) |
52 } | 52 } |
265 | 265 |
266 ret <- { inst: [ 0xC3u8 ] } | 266 ret <- { inst: [ 0xC3u8 ] } |
267 | 267 |
268 label <- { | 268 label <- { |
269 _offset <- -1 | 269 _offset <- -1 |
270 _address <- 0u64 | |
270 _forwardRefs <- #[] | 271 _forwardRefs <- #[] |
271 #{ | 272 #{ |
272 length <- { 0 } | 273 length <- { 0 } |
273 hasOffset? <- { _offset >= 0 } | 274 hasOffset? <- { _offset >= 0 } |
274 offset <- { _offset } | 275 offset <- { _offset } |
275 register? <- { false } | 276 register? <- { false } |
276 localLabel? <- { true } | 277 label? <- { true } |
277 flattenTo:at <- :dest :idx { | 278 flattenTo:at <- :dest :idx { |
278 if: (not: hasOffset?) { | 279 if: (not: hasOffset?) { |
279 _offset <- idx | 280 _offset <- idx |
281 _address <- dest addressAt: idx | |
280 foreach: _forwardRefs :idx fun { | 282 foreach: _forwardRefs :idx fun { |
281 fun: _offset | 283 fun: _offset |
282 } | 284 } |
283 _forwardRefs <- #[] | 285 _forwardRefs <- #[] |
284 } | 286 } |
294 } | 296 } |
295 } | 297 } |
296 } | 298 } |
297 | 299 |
298 jmp <- :jmpDest { | 300 jmp <- :jmpDest { |
299 if: (jmpDest localLabel?) { | 301 if: (jmpDest label?) { |
300 _size <- -1 | 302 _size <- -1 |
301 #{ | 303 #{ |
302 length <- { if: _size < 0 { 5 } else: { _size } } | 304 length <- { if: _size < 0 { 5 } else: { _size } } |
303 flattenTo:at <- :dest :idx { | 305 flattenTo:at <- :dest :idx { |
304 jmpDest withOffset: :off { | 306 jmpDest withOffset: :off { |
342 } else: { | 344 } else: { |
343 inst: 0xFFu8 | (mod_rm: (opex: 5u8) jmpDest) | 345 inst: 0xFFu8 | (mod_rm: (opex: 5u8) jmpDest) |
344 } | 346 } |
345 } | 347 } |
346 | 348 |
349 call <- :callDest { | |
350 if: (callDest label?) { | |
351 #{ | |
352 length <- { 5 } | |
353 flattenTo:at <- :dest :idx { | |
354 dest set: idx 0xE8u8 | |
355 callDest withOffset: :off { | |
356 rel <- off - (idx + 5) | |
357 dest set: (idx + 1) (uint8: rel) | |
358 dest set: (idx + 2) (uint8: (rshift: rel by: 8)) | |
359 dest set: (idx + 3) (uint8: (rshift: rel by: 16)) | |
360 dest set: (idx + 4) (uint8: (rshift: rel by: 24)) | |
361 } else: { | |
362 } | |
363 idx + 5 | |
364 } | |
365 } | |
366 } else: { | |
367 inst: 0xFFu8 | (mod_rm: (opex: 2u8) callDest) | |
368 } | |
369 } | |
347 | 370 |
348 main <- { | 371 main <- { |
349 foo <- label: | 372 foo <- label: |
350 bar <- label: | 373 bar <- label: |
374 baz <- label: | |
351 prog <- #[ | 375 prog <- #[ |
352 mov: rdi rax q | 376 mov: rdi rax q |
353 sub: 1 rdi q | 377 sub: 1 rdi q |
354 add: rdi rax q | 378 add: rdi rax q |
355 jmp: bar | 379 jmp: bar |
356 foo | 380 foo |
357 ret: | 381 ret: |
358 bar | 382 bar |
359 sub: 13 rax q | 383 sub: 13 rax q |
384 call: baz | |
360 jmp: foo | 385 jmp: foo |
386 baz | |
387 add: 1 rax q | |
388 ret: | |
361 ] | 389 ] |
362 | 390 |
363 ba <- bytearray executableFromBytes: prog | 391 ba <- bytearray executableFromBytes: prog |
364 res <- ba runWithArg: 24u64 | 392 res <- ba runWithArg: 24u64 |
365 print: (string: res) . "\n" | 393 print: (string: res) . "\n" |