void BL_instruction_parse()
{
unsigned int input_hex_num,temp_hex_num,imm32,imm10,imm11,input_PC;
unsigned char I1,I2,J1,J2,S;
//HexDump((char *)tmpbuf,64,0);
printf("Please input a hex machine code:\r\n");
scanf( "%x", &input_hex_num );
printf( "input_hex_num = %x\r\n", input_hex_num );
//根据我们产生的指令f7fffffe,
temp_hex_num = input_hex_num >>13;
J1 = temp_hex_num & 0x01;
printf( "J1 = %x\r\n", J1 );
temp_hex_num = input_hex_num >>11;
J2 = temp_hex_num & 0x01;
printf( "J2 = %x\r\n", J2 );
temp_hex_num = input_hex_num >>26;
S = temp_hex_num & 0x01;
printf( "S = %x\r\n", S );
I1 = !(J1 ^ S);
printf( "I1 = %x\r\n", I1 );
I2 = !(J2 ^ S);
printf( "I2 = %x\r\n", I2 );
imm10 = 0x00;
imm10 = input_hex_num;
imm10 = (imm10 >>16)&0x000003ff;
imm11 = 0x00;
imm11 = input_hex_num;
imm11 = (imm11 >>0)&0x000007ff;
imm32 = 0x00;
temp_hex_num = 0x00;
temp_hex_num = temp_hex_num | S;
temp_hex_num = temp_hex_num << 23;
imm32 = imm32 | temp_hex_num;
printf( "imm32 = %x\r\n", imm32 );
temp_hex_num = 0x00;
temp_hex_num = temp_hex_num | I1;
temp_hex_num = temp_hex_num << 22;
imm32 = imm32 | temp_hex_num;
printf( "imm32 = %x\r\n", imm32 );
temp_hex_num = 0x00;
temp_hex_num = temp_hex_num | I2;
temp_hex_num = temp_hex_num << 21;
imm32 = imm32 | temp_hex_num;
printf( "imm32 = %x\r\n", imm32 );
temp_hex_num = 0x00;
temp_hex_num = temp_hex_num | imm10;
temp_hex_num = temp_hex_num << 11;
imm32 = imm32 | temp_hex_num;
printf( "imm32 = %x\r\n", imm32 );
temp_hex_num = 0x00;
temp_hex_num = temp_hex_num | imm11;
temp_hex_num = temp_hex_num << 0;
imm32 = imm32 | temp_hex_num;
imm32 = imm32<<1;
if( S ){
imm32 = imm32 | 0xff000000;
}else{
imm32 = imm32 | 0x00000000;
}
printf( "imm32 = %x\r\n", imm32 );
printf( "imm32 = %d\r\n", imm32 );
printf("Please input a hex num PC value:\r\n");
scanf( "%x", &input_PC );
printf( "input_PC = %x\r\n", input_PC );
input_PC = input_PC + 4;
input_PC = input_PC + imm32;
printf( "go_PC = %x\r\n", input_PC );
#if 0
所以I1 = !(J1~S) = 1, I2 = !(J2~S) = 1,
imm32 = SignExtend(S:I1:I2:imm10:imm11:’0’,32) = SignExtend(1:1:1:11 1111 1111:111 1111 1110:’0’,32) = 1111 1111 1111 1111 1111 1111 1111 1100 = 0xfffffffc。
0xfffffffc是-4的补码,另外当前PC是0x00000006,
再根据上面的Operation最后一步BranchWritePC( PC + imm32)
最终跳转到0x6 + (-4) = 0x2的地址出,即函数fun_for_sub的地址,因此实现根据当前PC实现了地址无关性的代码。
在X86平台下面也是差不多的原理,使用的也是基于PC相关的跳转指令。《程序员的自我修养—链接、装载和库》讲得很好。
#endif
}