24.14 MIPS/Debian上嵌入式汇编中自动插入nop充任delay slot
http://scz.617.cn/unix/200904201502.txt
Q:
$ as -v GNU assembler version 2.17 (mips-linux-gnu) using BFD version 2.17 Debian GNU/Linux $ gcc-2.95 -v gcc version 2.95.4 20011002 (Debian prerelease)
int main ( int argc, char * argv[] ) { asm volatile ("
text_begin:
lui $3, %hi(0x51211314)
jalr $3
/*
* 我想让这条ori充任delay slot,结果编译下来,在jalr与ori之间自动插入
* 了nop指令充任delay slot,有办法禁止这个行为吗?
*/
ori $3, %lo(0x51211314)
");
return( 0 );
$ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/4i text_begin 0x400748 <text_begin>: lui v1,0x5121 0x40074c <text_begin+4>: jalr v1 0x400750 <text_begin+8>: nop // 自动插入nop充任delay slot 0x400754 <text_begin+12>: ori v1,v1,0x1314 (gdb)
编译过程中as自动在jalr指令后面插入nop充任delay slot,但这个行为干挠了我的 实验,有无办法禁止这种自动插入nop充任delay slot的行为。
D: Nineveh@SMTH
int main ( int argc, char * argv[] ) { asm volatile ("
text_begin:
li $3, 0x51211314
jalr $3
/*
* 我想让这条ori充任delay slot,结果编译下来,在jalr与ori之间自动插入
* 了nop指令充任delay slot,有办法禁止这个行为吗?
*/
ori $4, $0, 0x7F
");
return( 0 );
$ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/5i text_begin 0x400748 <text_begin>: lui v1,0x5121 0x40074c <text_begin+4>: ori v1,v1,0x1314 0x400750 <text_begin+8>: jalr v1 0x400754 <text_begin+12>: nop // 自动插入nop充任delay slot 0x400758 <text_begin+16>: li a0,0x7f (gdb)
关于delay slot,填什么指令是汇编器决定的,写的时候把"ori $4, $0, 0x7F"放到 jalr前面,汇编出来的ori就会被放到delay slot里。
int main ( int argc, char * argv[] ) { asm volatile ("
text_begin:
li $3, 0x51211314
ori $4, $0, 0x7F
jalr $3
");
return( 0 );
$ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/4i text_begin 0x400748 <text_begin>: lui v1,0x5121 0x40074c <text_begin+4>: ori v1,v1,0x1314 0x400750 <text_begin+8>: jalr v1 0x400754 <text_begin+12>: li a0,0x7f // 就是那条"ori $4, $0, 0x7F",现在是伪指令形式 (gdb)
A: scz@nsfocus 2009-04-20 15:02
由汇编器决定delay slot是什么无法满足我的原始需求,现在我需要精确控制每一条 汇编指令,即使我将错误的指令放在delay slot上也不能自动替我"修正"。
int main ( int argc, char * argv[] ) { asm volatile ("
text_begin:
lui $3, 0x5121
/*
* 我想让这条指令充任jalr的delay slot,若按Nineveh所述将该指令置于jalr
* 之前,最终并不能达到目的。
*/
ori $3, $3, 0x1314
jalr $3
");
return( 0 );
$ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/4i text_begin 0x400748 <text_begin>: lui v1,0x5121 0x40074c <text_begin+4>: ori v1,v1,0x1314 // 该指令未被放到delay slot上 0x400750 <text_begin+8>: jalr v1 0x400754 <text_begin+12>: nop (gdb)
我的原始需求动用".set noreorder"即可解决:
int main ( int argc, char * argv[] ) { asm volatile ("
.set noreorder
text_begin:
lui $3, %hi(0x51211314)
jalr $3
ori $3, %lo(0x51211314)
.set reorder
");
return( 0 );
$ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/3i text_begin 0x400748 <text_begin>: lui v1,0x5121 0x40074c <text_begin+4>: jalr v1 0x400750 <text_begin+8>: ori v1,v1,0x1314 // 这次没有自动插入nop
顺便说一句,我的原始实验如下:
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
0x51210000 in ?? () (gdb) i r v1 pc v1: 0x51211314 pc: 0x51210000
jalr导致跳转进行中,然后位于delay slot的ori指令被执行,这个实验仅仅是想验 证妄图以此方式跳转到0x51211314是不可能的,delay slot被执行时跳转已在进行中, delay slot不能用来改变跳转的目标地址。