我编译了这段代码:
int main()
{
int x;
try
{
x=2/0;
}
catch (...)
{
x=1;
}
return 0;
}
到 mips,这就是我得到的:
.file 1 "main.cpp"
.section .mdebug.abi32
.previous
.nan legacy
.gnu_attribute 4, 1
.abicalls
.option pic0
.text
.align 2
.globl main
.cfi_sections .eh_frame_entry
$LFB6 = .
.cfi_startproc
.set nomips16
.set nomicromips
.ent main
.type main, @function
main:
.frame $fp,24,$31 # vars= 8, regs= 1/0, args= 0, gp= 8
.mask 0x40000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-24
.cfi_def_cfa_offset 24
sw $fp,20($sp)
.cfi_offset 30, -4
move $fp,$sp
.cfi_def_cfa_register 30
li $2,2 # 0x2
move $3,$0
teq $3,$0,7
div $0,$2,$3
mfhi $2
mflo $2
sw $2,8($fp)
move $2,$0
.cfi_epilogue_begin
move $sp,$fp
.cfi_def_cfa_register 29
lw $fp,20($sp)
addiu $sp,$sp,24
.cfi_restore 30
.cfi_def_cfa_offset 0
j $31
nop
.set macro
.set reorder
.end main
.cfi_endproc
$LFE6:
.size main, .-main
.ident "GCC: (Sourcery CodeBench Lite 2014.11-22) 4.9.1"
我想特别询问指令teq
,我知道它的意思是“如果相等则陷阱”所以当被除数为零时它会陷阱(这里是零)。
我不明白的是 trap 之后发生了什么,我的意思是这个程序集文件中的 catch block 在哪里?在网上搜索时,我也看到了不同的东西,比如协处理器 0、异常代码寄存器……等等。
那么这里发生了什么?
最佳答案
teq
指令是编译器选择如何处理因除以零而导致的未定义行为;没有迹象表明除以零会触发 catch
block 将处理的异常。
然后您想知道 catch
block 出现在 list 中的什么位置。它没有。没有任何内容代表 x=1
语句,可能是因为此后从未使用过该赋值。 div
指令是另一个例子。将结果存入寄存器$0
,相当于丢弃结果。
如果您想了解如何处理异常,请使用 throw
语句。
在 MIPS 中,有异常的概念,但它不同于 C++ 的异常概念。根据 MIPS IV,当 teq
的前两个参数相等时,CPU 将发出陷阱异常信号并“将控制转移到内核中的软件异常处理程序”指令集手册。内核可能会打印一条消息并终止程序,除非程序要求内核做其他事情。 (您的编译器的运行时库可能已经提供了一些东西来控制 CPU 异常的处理,甚至可能将它们转换为可以在 catch
block 中捕获的 C++ 异常。)
teq
的第三个参数对 CPU 没有固有意义,但异常处理程序可能知道将 7
视为整数除以零的指示符。 ( float 除以零的处理方式不同,不一定是陷阱。)
关于c++ - teq如何在mips中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29999351/