diff options
Diffstat (limited to 'subx/ex7.subx')
-rw-r--r-- | subx/ex7.subx | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/subx/ex7.subx b/subx/ex7.subx new file mode 100644 index 00000000..c95ed361 --- /dev/null +++ b/subx/ex7.subx @@ -0,0 +1,90 @@ +## compute the factorial of 5, and return the result in the exit code +# +# To run: +# $ subx translate ex7.subx ex7 +# $ subx run ex7 +# Expected result: +# $ echo $? +# 120 + +== 0x08048054 # code segment, after leaving room for ELF header +# instruction effective address operand displacement immediate +# op subop mod rm32 base index scale r32 +# 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes + +# main: + # prepare to make a call +# 54 + 55/push # push EBP +# 55 + 89/copy 3/mod/direct 5/rm32/EBP 4/r32/ESP # copy ESP to EBP +# 57 + # factorial(5) + 68/push 5/imm32 # push 5 +# 5c + e8/call factorial/disp32 +# 61 + # discard arg + 5a/pop # pop into EDX +# 62 + # clean up after call + 89/copy 3/mod/direct 4/rm32/ESP 5/r32/EBP # copy EBP to ESP +# 64 + 5d/pop # pop to EBP + + # exit(EAX) +# 65 + 89/copy 3/mod/direct 3/rm32/EBX 0/r32/EAX # copy EAX to EBX +# 67 + b8/copy 1/imm32 # copy 1 to EAX +# 6c + cd/syscall 0x80/imm8 # int 80h + +# factorial(n) +# 6e +factorial: + # initialize n + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none 2/r32/edx 4/disp8 # copy *(ESP+4) to EDX +# 72 + # initialize EAX to 1 (base case) + b8/copy 1/imm32 # copy 1 to EAX +# 77 + # if (n <= 1) jump exit + 81 7/subop/compare 3/mod/direct 2/rm32/EDX 1/imm32 # compare EDX with 1 +# 7d + 7e/jump-if factorial:exit/disp8 # jump if <= to exit +# 7f + # EBX: n-1 + 89/copy 3/mod/direct 3/rm32/EBX 2/r32/EDX # copy EDX to EBX +# 81 + 81 5/subop/subtract 3/mod/direct 3/rm32/EBX 1/imm32 # subtract 1 from EBX +# 87 + # prepare call + 55/push # push EBP +# 88 + 89/copy 3/mod/direct 5/rm32/EBP 4/r32/ESP # copy ESP to EBP + # EAX: factorial(n-1) +# 8a + 53/push # push EBX +# 8b + e8/call factorial/disp32 +# 90 + # discard arg + 5e/pop # pop into ESI +# 91 + # clean up after call + 89/copy 3/mod/direct 4/rm32/ESP 5/r32/EBP # copy EBP to ESP +# 93 + 5d/pop # pop to EBP +# 94 + # refresh n + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/esp 4/index/none 2/r32/edx 4/disp8 # copy *(ESP+4) to EDX +# 98 + # return n * factorial(n-1) + 0f af/multiply 3/mod/direct 2/rm32/EDX 0/r32/EAX # multiply EDX (n) into EAX (factorial(n-1)) + # TODO: check for overflow +# 9b +factorial:exit: + c3/return + +# vim:ft=subx:nowrap:so=0 |