戦略
1. アセンブラと同じ操作をするCコードをline by lineで書いてみる
2. Sprinterを実際に動かして、入力値と出力値を調べる
解析用Arduinoプログラム
// intRes = intIn1 * intIn2 >> 16 // uses: // r26 to store 0 // r27 to store the byte 1 of the 24 bit result #define Hoge(intRes, charIn1, intIn2) \ asm volatile ( \ "clr r26 \n\t" \ "mul %A1, %B2 \n\t" \ "movw %A0, r0 \n\t" \ "mul %A1, %A2 \n\t" \ "add %A0, r1 \n\t" \ "adc %B0, r26 \n\t" \ "lsr r0 \n\t" \ "adc %A0, r26 \n\t" \ "adc %B0, r26 \n\t" \ "clr r1 \n\t" \ : \ "=&r" (intRes) \ : \ "d" (charIn1), \ "d" (intIn2) \ : \ "r26" \ ) // intRes = longIn1 * longIn2 >> 24 // uses: // r26 to store 0 // r27 to store the byte 1 of the 48bit result #define Foo(intRes, longIn1, longIn2) \ asm volatile ( \ "clr r26 \n\t" \ "mul %A1, %B2 \n\t" \ "mov r27, r1 \n\t" \ "mul %B1, %C2 \n\t" \ "movw %A0, r0 \n\t" \ "mul %C1, %C2 \n\t" \ "add %B0, r0 \n\t" \ "mul %C1, %B2 \n\t" \ "add %A0, r0 \n\t" \ "adc %B0, r1 \n\t" \ "mul %A1, %C2 \n\t" \ "add r27, r0 \n\t" \ "adc %A0, r1 \n\t" \ "adc %B0, r26 \n\t" \ "mul %B1, %B2 \n\t" \ "add r27, r0 \n\t" \ "adc %A0, r1 \n\t" \ "adc %B0, r26 \n\t" \ "mul %C1, %A2 \n\t" \ "add r27, r0 \n\t" \ "adc %A0, r1 \n\t" \ "adc %B0, r26 \n\t" \ "mul %B1, %A2 \n\t" \ "add r27, r1 \n\t" \ "adc %A0, r26 \n\t" \ "adc %B0, r26 \n\t" \ "lsr r27 \n\t" \ "adc %A0, r26 \n\t" \ "adc %B0, r26 \n\t" \ "clr r1 \n\t" \ : \ "=&r" (intRes) \ : \ "d" (longIn1), \ "d" (longIn2) \ : \ "r26" , "r27" \ ) int timer; int timer2; uint8_t tmp_step_rate; uint8_t tmp_step_rate2; int gain; int gain2; // int acc_step_rate; // long acceleration_time; // long acceleration_rate; void setVar(){ timer = 0; // tmp_step_rate = tmp_step_rate2 = B01001111; //8bit // gain = gain2 = (B01001111 * 256) + B00001111;//16bit tmp_step_rate = tmp_step_rate2 = 247; //8bit gain = gain2 = 117;//16bit } void setup() { // put your setup code here, to run once: Serial.begin(115200); //----------------------------------- Serial.println("******"); // tmp_step_rate2 = B01111111; //8bit // gain2 = (B01111111 * 256) + B01111111;//16bit setVar(); Hoge(timer2, tmp_step_rate2, gain2); Serial.println("A*B >> 16 (ASM)"); printBits(timer2>>8);printBits(timer2); Serial.println(); Serial.println(timer2,DEC); Serial.println("******"); //----------------------------------- //----------------------------------- // assembler line-by-line emulation uint8_t r26 = 0; uint8_t a0,b0; // output uint8_t a1,a2,b2; //input a1 = tmp_step_rate; a2 = gain; b2 = gain >> 8; int r1r0 = (int)a1*(int)b2; uint8_t r1 = r1r0 >> 8; uint8_t r0 = r1r0; a0 = r0; r1r0 = (int)a1*(int)a2; r1 = r1r0 >> 8; r0 = r1r0; a0 = a0 + r1; b0 = r26; r0 = r0 >> 1; a0 = a0 + r26; b0 = b0 + r26; r1 = 0; int result = (b0<<8) + a0; printBits(b0);printBits(a0); Serial.println(); Serial.println(result,DEC); //----------------------------------- //----------------------------------- // tmp_step_rate = 0x0F; //8bit // gain = 0x0002;//16bit Serial.println("******"); setVar(); Serial.print("tmp_step_rate: ");Serial.print(tmp_step_rate,DEC);Serial.print(" ");printBits(tmp_step_rate); Serial.println(); Serial.print("gain: ");Serial.print(gain);Serial.print(" "); printBits(gain/256); printBits(gain%256); Serial.println(); long hoge = ((long) tmp_step_rate * (long) gain); //32bit Serial.print(tmp_step_rate,DEC); Serial.print("x"); Serial.print(gain,DEC); Serial.print("="); Serial.println(hoge); Serial.print("Full bits: "); printBits(hoge >> 16); printBits(hoge >> 8); printBits(hoge); Serial.println(); char moge = (hoge) >> 16; Serial.print(">>16 bits shift: "); printBits(moge>>8);printBits(moge); Serial.println(); Serial.println(moge,DEC); Serial.println("******"); //----------------------------------- // acceleration_time = 0x00000001 ; //32bit // acceleration_rate = 0x00000001 ; //32bit // Serial.println("compute2"); // Foo(acc_step_rate, acceleration_time, acceleration_time); // Serial.println(acceleration_time); // Serial.println(acceleration_rate); // Serial.println(acc_step_rate); } void printBits(byte myByte){ for(byte mask = 0x80; mask; mask >>= 1){ if(mask & myByte) Serial.print('1'); else Serial.print('0'); } } void loop() { // put your main code here, to run repeatedly: }