📄 crt0.s
字号:
/*** Called as start(argc, argv, envp)*//* gs:edx points to prog_info structure. All other registers are OBSOLETE** but included for backwards compatibility*//* These symbols are for global constructors and destructors */#if 0 .section .ctor .globl ___go32_first_ctor___go32_first_ctor: .section .dtor .globl ___go32_last_ctor___go32_last_ctor: .globl ___go32_first_dtor___go32_first_dtor: .data .globl ___go32_last_dtor___go32_last_dtor:#endif .text .globl _start_start: .globl startstart:#ifdef EMU387 pusha push %gs#endif movl %eax,__hard_master movl %esi,___pid movl %edi,___transfer_buffer movl %ebx,_ScreenPrimary movl %ebp,_ScreenSecondary cmpl $0, %edx je Lcopy_none movw %gs,%cx movw %ds,%ax cmpw %cx,%ax je Lcopy_none movl %gs:(%edx), %ecx cmpl __go32_info_block, %ecx jbe Lcopy_less movl __go32_info_block, %ecxLcopy_less: movl $__go32_info_block, %edi addl $3, %ecx andl $0xfffffffc, %ecx movl %ecx, (%edi) addl $4, %edi addl $4, %edx subl $4, %ecxLcopy_more: movl %gs:(%edx), %eax movl %eax, (%edi) addl $4, %edx addl $4, %edi subl $4, %ecx jnz Lcopy_more movl __go32_info_block+4, %eax movl %eax, _ScreenPrimary movl __go32_info_block+8, %eax movl %eax, _ScreenSecondary/* Backward compatibility - do not copy this one!** movl __go32_info_block+12, %eax** movl %eax, ___transfer_buffer*/ movl __go32_info_block+20, %eax movl %eax, ___pid movl __go32_info_block+24, %eax movl %eax, __hard_master jmp Lcopy_doneLcopy_none: movl %ebx,__go32_info_block+4 movl %ebp,__go32_info_block+8 movl %edi,__go32_info_block+12 movl $4096,__go32_info_block+16 movl %esi,__go32_info_block+20 movl %eax,__go32_info_block+24 movl $28, __go32_info_blockLcopy_done:#ifndef EMU387 call __setstack#endif xorl %esi,%esi xorl %edi,%edi xorl %ebp,%ebp xorl %ebx,%ebx movl %esp,%ebx#ifdef MAKE_GCRT0 call mcount_init /* initialize the profiler */#endif movl 8(%ebx),%eax pushl %eax movl %eax,_environ pushl 4(%ebx) pushl (%ebx) call ___main call _main addl $12,%esp#ifdef EMU387 pop %gs popa#else pushl %eax call _exitexit_again: movl $0x4c00,%eax int $0x21 jmp exit_again#endif ret#ifdef MAKE_GCRT0 .globl __exit__exit: call mcount_write /* make sure we dump the output */exit_again2: movb 4(%esp),%al movb $0x4c,%ah int $0x21 jmp exit_again2/* Here is where we initialize the timer interrupt - specific to go32 *//* In this case, the timer calls mcount_isr */ .globl mcount_isr_initmcount_isr_init: movw __go32_info_block+36, %ax /* run mode */ cmp $1,%ax jb skip_mcount cmp $3,%ax ja skip_mcount movw $16,%ax movw %ax,%gs movzbl __hard_master,%eax /* timer is on irq 0 */ shll $3,%eax /* times 8 bpv *//* movl $960,%eax vector 0x78 * 8 bpv */ movw %gs:(%eax),%cx movw %cx,mc_chain movw %gs:6(%eax),%cx movw %cx,mc_chain_hi movw %gs:2(%eax),%cx movw %cx,mc_chain_sel movl $mcount_isr,%ecx movw %cx,%gs:(%eax) movw $0xd8,%gs:2(%eax) /* selector 27 == 32-bit code */ movw $0x8f00,%gs:4(%eax) rorl $16,%ecx movw %cx,%gs:6(%eax) movw %ds,%ax movw %ax,%gsskip_mcount: movl mcount_histogram,%eax movl $1,(%eax) ret/* Obtain the PC where we interrupted, and bump the histogram. We should *//* do error checking here, but we don't. This routine is specific to go32 *//* in some spots */mcount_isr: pushl %eax cmpl $1,mcount_skip je L0 movl 4(%esp),%eax /* get the PC */ subl $0x1020,%eax /* to fit in low..high */ andl $0xfffffffc,%eax shrl $1,%eax /* now points to one 4-byte entry */ addl mcount_histogram,%eax incw (%eax)L0: popl %eax ljmp mc_chain /* chain to the next timer vector */ iret#endif .data .globl _environ_environ: .long 0 .globl ___pid___pid: .long 42 .globl ___transfer_buffer___transfer_buffer: .long 0 .globl _ScreenPrimary_ScreenPrimary: .long 0 .globl _ScreenSecondary_ScreenSecondary: .long 0 .globl __hard_master .globl __hard_slave .globl __core_select__hard_master: .byte 0__hard_slave: .byte 0__core_select: .short 0#ifdef MAKE_GCRT0mc_chain: .short 0mc_chain_hi: .short 0mc_chain_sel: .short 0#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -