我正在尝试在MIPS上重现调用堆栈,有关详细信息,请查看我之前的问题: How to get a call stack backtrace?(GCC,MIPS,no frame pointer) 由于MIPS没有帧指针,为此我必须在堆栈上找到返回地址。 我已经在其中一个函数的开头检查了ra寄存器(在它被推送到堆栈之前)并发现它包含未对齐的返回地址。
ra = 0x*******5
为什么会发生这种情况?
答案 0 :(得分:3)
我怀疑你是否正在链接microMIPS目标(16位指令,GCC选项08/01/2017 17:47:09,spid16s,Unknown,frame procname=NewInvoice.dbo.usp_EInvoice_UpdateReviewedDate line=130 stmtstart=8334 stmtend=9454 sqlhandle=0x0300080001b9aa5699653d00cea200000100000000000000
08/01/2017 17:47:09,spid16s,Unknown,UPDATE
08/01/2017 17:47:09,spid16s,Unknown,dbo.EInvoice
08/01/2017 17:47:09,spid16s,Unknown,SET
08/01/2017 17:47:09,spid16s,Unknown,ReviewedDate = @ReviewedDate
08/01/2017 17:47:09,spid16s,Unknown,<c/>FirstReviewedDate = @FirstReviewedDate
08/01/2017 17:47:09,spid16s,Unknown,<c/>EInvoiceStatusID = @EInvoiceStatusID
08/01/2017 17:47:09,spid16s,Unknown,<c/>DateUpdated = GETDATE()
08/01/2017 17:47:09,spid16s,Unknown,<c/>ServicerClickChargeDate = @ServicerClickChargeDate
08/01/2017 17:47:09,spid16s,Unknown,<c/>ServicerClickChargeAmount = @ServicerClickChargeAmount
08/01/2017 17:47:09,spid16s,Unknown,<c/>OrdinalNumForDptLoanVnd = @OrdinalNumForDptLoanVnd
08/01/2017 17:47:09,spid16s,Unknown,<c/>OrdinalNumForDptLoanReferral = @OrdinalNumForDptLoanReferral
08/01/2017 17:47:09,spid16s,Unknown,<c/>OrdinalNumForReferralTypeLoanVnd = @OrdinalNumForReferralTypeLoanVnd
08/01/2017 17:47:09,spid16s,Unknown,WHERE EInvoiceID = @EInvoiceID
),或许?
假设这是正确的,请从 microMIPS GCC Toolchain Usage 文档:
使处理器能够确定当前的ISA(MIPS32 ISA或 microMIPS ISA),地址(位0)的最低有效位是 用作ISA模式位(0 = MIPS32 ISA,1 = microMIPS ISA)。这个 机制允许通过JALR调用microMIPS或MIPS32函数 通过设置寄存器值奇数(对于microMIPS)或甚至是指令 (对于MIPS32)来自地址。
通过这种方式,为microMIPS编译的函数可以调用为MIPS32编译的函数,反之亦然,通过将函数的低阶地址(或返回地址,跳转目标等)设置为0(对于MIPS32或1)用于microMIPS。由于所有指令都是16位或32位且必须相应地对齐,要找到实际返回地址,只需屏蔽低位即可。