0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 .text
0011
0012 .global call32_from_64
0013 .type call32_from_64, @function
0014 call32_from_64:
0015 // rdi: stack to use
0016 // esi: function to call
0017
0018 // Save registers
0019 pushq %rbx
0020 pushq %rbp
0021 pushq %r12
0022 pushq %r13
0023 pushq %r14
0024 pushq %r15
0025 pushfq
0026
0027 // Switch stacks
0028 mov %rsp,(%rdi)
0029 mov %rdi,%rsp
0030
0031 // Switch to compatibility mode
0032 pushq $0x23
0033 pushq $1f
0034 lretq
0035
0036 1:
0037 .code32
0038 // Call the function
0039 call *%esi
0040 // Switch back to long mode
0041 jmp $0x33,$1f
0042 .code64
0043
0044 1:
0045 // Restore the stack
0046 mov (%rsp),%rsp
0047
0048 // Restore registers
0049 popfq
0050 popq %r15
0051 popq %r14
0052 popq %r13
0053 popq %r12
0054 popq %rbp
0055 popq %rbx
0056
0057 ret
0058
0059 .size call32_from_64, .-call32_from_64
0060
0061 .section .note.GNU-stack,"",%progbits