24.14 MIPS/Debian上嵌入式汇编中自动插入nop充任delay slot https://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 ); } /* end of main */ -------------------------------------------------------------------------- $ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/4i text_begin 0x400748 : lui v1,0x5121 0x40074c : jalr v1 0x400750 : nop // 自动插入nop充任delay slot 0x400754 : 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 ); } /* end of main */ -------------------------------------------------------------------------- $ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/5i text_begin 0x400748 : lui v1,0x5121 0x40074c : ori v1,v1,0x1314 0x400750 : jalr v1 0x400754 : nop // 自动插入nop充任delay slot 0x400758 : 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 ); } /* end of main */ -------------------------------------------------------------------------- $ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/4i text_begin 0x400748 : lui v1,0x5121 0x40074c : ori v1,v1,0x1314 0x400750 : jalr v1 0x400754 : 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 ); } /* end of main */ -------------------------------------------------------------------------- $ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/4i text_begin 0x400748 : lui v1,0x5121 0x40074c : ori v1,v1,0x1314 // 该指令未被放到delay slot上 0x400750 : jalr v1 0x400754 : 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 ); } /* end of main */ -------------------------------------------------------------------------- $ gcc-2.95 -Wall -pipe -o mips_inline_asm mips_inline_asm.c $ gdb ./mips_inline_asm (gdb) x/3i text_begin 0x400748 : lui v1,0x5121 0x40074c : jalr v1 0x400750 : 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不能用来改变跳转的目标地址。