35.2.1.7. ВЫЗОВ И ВОЗВРАТ ИЗ ПОДПРОГРАММ, БЕЗУСЛОВНЫЕ ПЕРЕХОДЫ




Call subroutine

Собственно основные варианты: Direct - когда смещение куда переходить описано в команде Indirect - когда абсолютный адресс куда переходить береться из регистра и Адресс возврата записывается в stack (типично для CISC) Адресс возврата записывается в специальный Link register (типично для RISC) Direct/Stack:

	Push(Instruction_Pointer)
	Instruction_Pointer = Instruction_Pointer + Relative_Offset


Indirect/Stack:



	Push(Instruction_Pointer)
	Instruction_Pointer = Source	


Direct/Link register:



	Link_Register = Instruction_Pointer
	Instruction_Pointer = Instruction_Pointer + Relative_Offset
Например для SPARC:
	call	address

		jmpl	address, %o8	! Jump and Link


Indirect/Link register:



	Link_Register = Instruction_Pointer
	Instruction_Pointer = Source
------------------------------------------------------------------------------ o Call Subroutine x86 CALL REL(16,32) ---------------------------------------- Alpha BSR PREL(20) JSR RR (full 64bit jump) ---------------------------------------- PPC (*) BL/BLA and then save Link Register. ---------------------------------------- MIPS (*) JAL/JALR and then save Link Register. ---------------------------------------- SPARC CALL PREL(?) ---------------------------------------- 68K BSR PREL(16) JSR R ADDR(32) (D-,A- regs) ---------------------------------------- z80 CALL [cc] ADDR(16) ---------------------------------------- HPPA BL REL(17),R (and then save Link Reg) BLR R,R BV R(R) (Branch Vectored) ------------------------------------------ IA-64 BR.CALL ?? ----------------------------------------- MCS51 ACALL ADDR(11) LCALL ADDR(16) ----------------------------------------- JVM JSR REL16 JSR_W REL32 ----------------------------------------- ARM BLcc label (Branch and Link) ----------------------------------------- SH4 BSR label JSR @R


Return from subroutine

Соответсвенно есть два варианта для возврата: из стека (типично для CISC) из Link Register (типично для RISC) Return (stack):

	Pop(Instuction_Pointer)
Return (Link Register)

	Instruction_Pointer = Link_Register
Часто на RISC - Return - это такой же Call, но в качестве назначения выступает регистр равный 0. Например SPARC:
	ret	=>	jmpl	%i7+8,%g0
	retl	=>	jmpl	%o8+8,%g0	! for leaf subroutines
------------------------------------------------------------------------------ o Return from subroutine x86 RET (xx - deleted frame) ----------------------------------------- Alpha RET RR (full 64bit ret) ----------------------------------------- PPC (*) Fetch from stack, and then BL/BLA ----------------------------------------- MIPS (*) Fetch from stack, and then JR ----------------------------------------- SPARC ???? ----------------------------------------- 68K RTS ----------------------------------------- z80 RET [cc] ----------------------------------------- HPPA (*) Fetch from stack, then BLR ------------------------------------------ IA-64 BR.RET ??? ----------------------------------------- MCS51 RET ----------------------------------------- JVM RET FRAME_PTR RET_W FRAME_PTR IRETURN (Return from function integer) LRETURN (long) FRETURN (float) DRETURN (double) ARETURN (object) RETURN (null) ------------------------------------------ ARM (*) ??? ------------------------------------------ Sh4 RTS


Unconditional Jump

Безусловные переходы тоже бывают Direct и Indirect Direct:

	Instruction_Pointer = Instruction_Pointer + Relative_Offset
Indirect:

	Instruction_Pointer = Link_Register
Например для SPARC безусловный переход это тот-же уже хорошо знакомый нам Jump and Link, только в качестве получателя используется регистр всегда равный нулю.
	jmp	address

		jmpl	address,%g0
Часто RISC процессоры имеют особую форму инструкции безусловного перехода с большим количеством битов под Offset. Например если 32-разрядный RISC процессор имеет инсрукцию у которой 30-бит выделено на offset, то он одной командой перехода может достичь любого места памяти (так как типичные RISC команды имеют размер 32-бита и выровнены по адрессу кратному 4 байтам). ------------------------------------------------------------------------------ o Unconditional JUMP x86 JMP REL(8,16,32) ------------------------------------- Alpha BR PREL(20) (different prediction logic) JMP RR (full 64-bit) ------------------------------------- PPC B PREL(26) (relative) BL PREL(26) (branch to Link register) BA ADDR(26) (absolute) BLA ADDR(26) (absolute to Link Register) ------------------------------------- MIPS J PADDR(28) JR R (register) JAL PADDR(28) (Jump and Link) JALR RR (Jump and Link register) ------------------------------------- SPARC B PREL(?) JMPL PREL(?)R (Jump and Link) ------------------------------------- 68K BRA PREL(16) JMP R ADDR(32) (D-,A- regs) ------------------------------------- z80 JR PREL(8) JP ADDR(16) A ------------------------------------- HPPA (*) conditional jump with ALWAYS flag and zero reg. ------------------------------------------ IA-64 BR.XXX MOV R1 = B1 (Move Branch Register) B1 = R1 --------------------------------------- MCS51 AJMP ADDR(11) LJMP ADDR(16) SJMP REL(8) JMP @A+DPTR --------------------------------------- JVM GOTO REL16 GOTO_2 REL32 --------------------------------------- ARM Bcc label (Branch) --------------------------------------- SH4 BRA lable JMP @R ------------------------------------------------------------------------------ Note: More operations: PUSH to stack POP from stack. And general stack frame operations.

Index Prev Next