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.
This commit is contained in:
Kartik Agaram 2018-09-21 15:10:34 -07:00
parent 0d8d7618f1
commit d9818a5333
2 changed files with 49 additions and 0 deletions

BIN
subx/examples/ex9 Executable file

Binary file not shown.

49
subx/examples/ex9.subx Normal file
View File

@ -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