単純な例によるARMプロセッサのメモリアライメントについて

ポインターを受け取る関数があるとします。 ヌルターミナル文字列がポインターにあり、その後に4バイト整数が続くことがわかります。 タスクは、コンソールに文字列と全体を表示することです。 次のように解決できます。



void foo(void* data_ptr) { //       char* str = (char*)data_ptr; //            int* value = (int*)(str+strlen(str)+1); //    printf("%s %d", str, *value); }
      
      





かなり簡単な作業ですね。 コンピューター(x86)で確認します。すべて問題ありません。 ARMを使用してボードにロードします。 そして、自分自身を足で撃つ時間がないので、熊手を踏んでいます。 文字列の内容に応じて、整数値は通常または曲線として表示されます。 ポインタをチェックし、それらが指すメモリをチェックします。 すべてが正常です。



文字列の長さが3、7、11、...、4 * n-1の場合、整数が正確に出力されることに注意してください。 うん。 「曲がった」ケースのメモリと出力を詳しく調べます。 たとえば、メモリが次のように見える場合:



住所:



 |0x00|0x01|0x02|0x03|0x04|0x05|0x06|0x07|0x08|
      
      





データ:



 |0x31|0x31|0x31|0x31|0x00|0x01|0x00|0x00|0x00|
      
      





出力では、文字列「1111」と0x00000001ではなく整数0x00000100を取得します。



結論:ポインター0x05で*値式を使用しているにもかかわらず、呼び出しはポインター0x04(または4の別の倍数)にあるかのようにデータが返されます。



それでは、そのような問題を解決する方法は? など:



 void foo(void* data_ptr) { int value; //    char* str = (char*)data_ptr; memcpy(&value, str+strlen(str)+1, sizeof(int)); //    printf("%s %d", str, value); //  }
      
      





この場合、すべてが常に配置されています。

ご清聴ありがとうございました!



UPD:明らかなエラーを修正しました。



All Articles