From d9818a5333805148586b7ac14c22f5dd413f593e Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 21 Sep 2018 15:10:34 -0700 Subject: 4575 New example, just to fix in my head how arguments go on the stack. It's possible I'm still confused about the order callers push args in to the stack. But even if this violates the calling convention, it should still run. --- subx/examples/ex9 | Bin 0 -> 129 bytes subx/examples/ex9.subx | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100755 subx/examples/ex9 create mode 100644 subx/examples/ex9.subx diff --git a/subx/examples/ex9 b/subx/examples/ex9 new file mode 100755 index 00000000..874efe52 Binary files /dev/null and b/subx/examples/ex9 differ diff --git a/subx/examples/ex9.subx b/subx/examples/ex9.subx new file mode 100644 index 00000000..aa519dc1 --- /dev/null +++ b/subx/examples/ex9.subx @@ -0,0 +1,49 @@ +## Example showing arg order on the stack. +# Show difference between ascii codes of first letter of first arg and first +# letter of second arg. +# +# To run: +# $ subx translate ex9.subx ex9 +# $ subx run ex9 z x +# Expected result: +# $ echo $? +# 2 +# +# At the start of a SubX program: +# argc: *ESP +# argv[0]: *(ESP+4) +# argv[1]: *(ESP+8) +# ... +# Locals start from ESP-4 downwards. + +== code +# 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 + # s1 = argv[1] (EAX) + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 0/r32/EAX 8/disp8 . # copy *(ESP+8) to EAX + # s2 = argv[2] (EBX) + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 3/r32/EBX 0xc/disp8 . # copy *(ESP+12) to EBX + # call string_equal(s1, s2) + # push args + 50/push . . . . . . . . # push EAX + 53/push . . . . . . . . # push EBX + # call + e8/call ascii_difference/disp32 + # discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add 8 to ESP + # exit(EAX) + 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX + b8/copy . . . . . . . 1/imm32/exit # copy 1 to EAX + cd/syscall . . . . . . . 0x80/imm8 # int 80h + +ascii_difference: # (s1, s2) : null-terminated ascii strings + # a = first letter of s1 (ECX) + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 0/r32/EAX 8/disp8 # copy *(ESP+8) to EAX + 8b/copy 0/mod/indirect 0/rm32/EAX . . . 0/r32/EAX . . # copy *EAX to EAX + # b = first letter of s2 (EDX) + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none 1/r32/ECX 4/disp8 # copy *(ESP+4) to ECX + 8b/copy 0/mod/indirect 1/rm32/ECX . . . 1/r32/ECX . . # copy *ECX to ECX + # a-b + 29/subtract 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # subtract ECX from EAX + c3/return -- cgit 1.4.1-2-gfad0