Recursion call should be exactly the same as an ordinate function call. The following is an example of asm code gen for function definition and recursive function call. Code gen to VM code should be similar. Hope it help.
The generated code would be (all numbers are 10-based instead of hex for simplicity):
fn_foo:
push ebp ; save the caller's old frame pointer
mov ebp, esp ; the new frame pointer to current stack ptr
sub esp, 20 ; make new space in stack for params and locals
; EBP points to the base of the current frame
; the frame has 20 bytes in the stack
; var1 at [ebp-4]
; var2 at [ebp-8]
; var3 at [ebp-12]
; param1 at [ebp-16]
; param2 at [ebp-20]
...
mov [ebp-4], 1 ; assign 0x1 to var1
mov [ebp-8], 2 ; assign 0x2 to var2
add [ebp-8], [ebp-16] ; add param1 to var2
...
push [ebp-4] ; push var1 for the function call
push [ebp-8] ; push var2 for the function call
call fn_foo ; call function foo at address fn_foo
; the current EIP is saved in stack
; the return value will be in EAX
mov [ebp-12], eax ; save function return value to var3
...
mov eax, [ebp-12] ; set function return value from var3
mov esp, ebp ; pop frame
pop ebp ; restore old EBP to previous frame
ret ; return to the caller by popping the
; caller's address from stack into EIP.
; Execution will continue at the restored EIP address.
Assume the following AST.
The generated code would be (all numbers are 10-based instead of hex for simplicity):