diff --git a/py/asmx86.c b/py/asmx86.c index 23160c9c20..e4736251f8 100644 --- a/py/asmx86.c +++ b/py/asmx86.c @@ -403,7 +403,7 @@ void asm_x86_entry(asm_x86_t *as, int num_locals) { asm_x86_push_r32(as, ASM_X86_REG_EBX); asm_x86_push_r32(as, ASM_X86_REG_ESI); asm_x86_push_r32(as, ASM_X86_REG_EDI); - num_locals |= 1; // make it odd so stack is aligned on 16 byte boundary + num_locals |= 3; // make it odd so stack is aligned on 16 byte boundary asm_x86_sub_r32_i32(as, ASM_X86_REG_ESP, num_locals * WORD_SIZE); as->num_locals = num_locals; } @@ -497,8 +497,14 @@ void asm_x86_push_local_addr(asm_x86_t *as, int local_num, int temp_r32) #endif void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r32) { - // TODO align stack on 16-byte boundary before the call assert(n_args <= 5); + + // Align stack on 16-byte boundary during the call + unsigned int align = ((n_args + 3) & ~3) - n_args; + if (align) { + asm_x86_sub_r32_i32(as, ASM_X86_REG_ESP, align * WORD_SIZE); + } + if (n_args > 4) { asm_x86_push_r32(as, ASM_X86_REG_ARG_5); } @@ -521,7 +527,7 @@ void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r // the caller must clean up the stack if (n_args > 0) { - asm_x86_add_i32_to_r32(as, WORD_SIZE * n_args, ASM_X86_REG_ESP); + asm_x86_add_i32_to_r32(as, (n_args + align) * WORD_SIZE, ASM_X86_REG_ESP); } }