今だけ人気マンガ100円レンタル特集♪

Arduino言語で書かれたプログラムがArduinoIDEでどのような機械語に翻訳されているか、ちょっと興味があり確かめてみたくなりました。
コンパイル結果を機械語(アセンブラ)で表示する方法教えてください。

ArduinoIDEのオプションなど探してみたのですが、表示方法がみつからなかったので、よろしくお願いします。

質問者からの補足コメント

  • HAPPY

    備忘録の意味を込めて書きます。
    arduino.exe を実行し、対象となるスケッチをコンパイルすると、
    C:\Users\ユーザ名\AppData\Local\Temp\

     arduino_build_*****
    が作成され、そこの スケッチ名.ino.elf を
    \hardware\tools\avr\binにあるavr-objdump.exeを使って
    コマンドプロンプトで

    avr-objdump -S -h -t -r スケッチ名.ino.elf>スケッチ名.txt

    を実行することで、
     コンパイル結果を機械語(アセンブラ)で表示すること
    ができました。

    スケッチ内の変数名や関数名は完全に失われているので、ソースと翻訳結果の対応づけは面倒でした。

      補足日時:2017/09/22 07:41

A 回答 (3件)

>ArduinoアセンブラでLチカ


http://qiita.com/TakeoChan/items/8362eaf53cf1992 …

>【Arduino】アセンブラ入門 その1
http://nn-hokuson.hatenablog.com/entry/2017/09/1 …

>arduinoの逆アセンブラーリスト
http://blog.goo.ne.jp/cookchant/e/2e7d037ebaea8f …

 こういう感じらしいです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
参考にさせていただきます。

お礼日時:2017/09/21 18:56

リンカはlssという拡張子の、ソースとアセンブラを交互に示したようなファイルも出力できます。


Arduinoは徹底的ににそういう情報をユーザーに見せないようにしているはなぜなんだろうと思います。
あくまで気軽に使えるオモチャであり、デバッグなんて専門的なことはさせないという強固な意志を感じますね。
    • good
    • 0
この回答へのお礼

追加の回答ありがとうございます。
>Arduinoは徹底的ににそういう情報をユーザーに見せないようにしているはなぜなんだろうと思います。
同感です。
Arduinoは8ビットマシンなので、メモリ空間が小さく、
ちょっとしたループ、たとえば
for(i=0; i<100; i++) の 変数i は、8bit で十分なので、
int は8ビットの方がふさわしいと思っていたのですが、コンパイル結果からすると16ビットで扱っていましたね。

>あくまで気軽に使えるオモチャであり、デバッグなんて専門的なことはさせないという強固な意志を感じますね。
なるほど、そのように理解するのですね。参考になります。
「動きゃいい」のではなく、「美しいコードで動いてほしい」と思う美意識の自己満足派には辛い仕様ということですね。

今回のコンパイル結果から、
 char か byte で変数宣言しないと、非効率な美しくないコードになってしまう
こと、確認しました。

お礼日時:2017/09/24 09:18

変に苦労するよりAtmel Studio7にスケッチを取りこめば、吐き出したアセンブラリストが見れたりシミュレーションできたりデバッグ出来たり、いろいろ便利で快適だと思います。

    • good
    • 0
この回答へのお礼

回答ありがとうございます。
Atmel Studio7ですね。

#インストーラーダウンロートしました。 880MBでか!
チラ見するだけにしては本格的ですね。
ありがとうございます。

お礼日時:2017/09/21 18:54

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QC言語 時刻差分の算出方法

教えて下さい。

C言語を用いてプログラミングをしています。
時刻をマイコン内部で1分毎にカウントしていますが、
外部入力があった際は、時刻を外部入力値に更新します。

時刻は以下の構造体で構成しています。

[年] 0x00~0x63 未設定:0x00
[月] 0x01~0x0c 未設定:0x00
[日] 0x01~0x1f 未設定:0x00
[時] 0x00~0x17 未設定:0xff
[分] 0x00~0x3b 未設定:0xff
[曜] 0x01~0x07 未設定:0x00

-----------------------------------------------------
typedef struct {
 unsigned char year_dt;
 unsigned char month_dt;
 unsigned char day_dt;
 unsigned char hour_dt;
 unsigned char min_dt;
 unsigned char week_dt;
}CALENDER_INFO;

CALENDER_INFO Calender_Before;
CALENDER_INFO Calender_After;

void Calender_Update(void){

 /* 処理前の時刻取得 */
 Calender_Before= Calender_Data;

 if(FLG_ON == F_SOUSA_A){
  Calender_Data = Calender_a;   /* 外部操作[a]データ反映 */
 }else{
  if(FLG_ON == F_SOUSA_B){
   Calender_Data = Calender_b;   /* 外部操作[b]データ反映 */
  }else{
   Add_1min_Calender();     /* 操作無ければ1分進める */
  }
 }

 /* 処理後の時刻取得 */
 Calender_After = Calender_Data;

 /* 差分算出 */
 ???????

return;
}
-----------------------------------------------------

時刻は[正]又は[負]のどちらの方向にも変更される可能性があります。

処理前の時刻情報と処理後の時刻情報をメンバ毎に演算するしかないのでしょうか?
演算の際に時刻の繰り上がりや繰り下がりを考慮しますと、
膨大なif文だらけになりバグが多発していまうのではないかと懸念しております。

初歩的な質問で申し訳ありませんが、
時刻計算にお詳しい方がいらっしゃいましたらご教示宜しくお願い致します。

教えて下さい。

C言語を用いてプログラミングをしています。
時刻をマイコン内部で1分毎にカウントしていますが、
外部入力があった際は、時刻を外部入力値に更新します。

時刻は以下の構造体で構成しています。

[年] 0x00~0x63 未設定:0x00
[月] 0x01~0x0c 未設定:0x00
[日] 0x01~0x1f 未設定:0x00
[時] 0x00~0x17 未設定:0xff
[分] 0x00~0x3b 未設定:0xff
[曜] 0x01~0x07 未設定:0x00

-----------------------------------------------------
typedef struct {
 unsigned cha...続きを読む

Aベストアンサー

日付時刻の構造体は自作のものでなきゃいけない理由はあるのでしょうか?
tm構造体を使えば二つの時間の差も簡単に出せます

time関数を使えるならtm構造体を使わず差を算出できます

文章で書くとややこしくなりそうなので参考サイトを貼ります
http://www.c-tipsref.com/tips/time/time.html
http://www1.cts.ne.jp/~clab/hsample/Time/Time5.html

QC言語について質問お願いします まだ勉強中なのでご指導よろしくお願いします str1=big str

C言語について質問お願いします

まだ勉強中なのでご指導よろしくお願いします

str1=big
str2=city
str3=bigcity

という結果にしたいのですが下のような結果になり困っております(´;Д;`)

もっといい書き方もあるかもしれませんが、今書いてあるコードを活かして訂正して結果通りになるにはどうすればいいでしょうか?!

その他アドバイスありましたら先輩方よろしくお願いしますm(_ _)m

Aベストアンサー

一つ訂正します
誤) char str1[4]={"big"},str2[4]={"city"}, str3[1]={0};
正) char str1[4]={"big"},str2[5]={"city"}, str3[1]={0};

ベテランでもこういう単純な間違いをすることがあります。
間違えもいいんです。それに気付いて直せれば。

ダメなときは、どこでダメになっているかを調べ、何故ダメになるかを調べ、どうすればダメじゃなくなるかを考えます。
これはベテランでも初心者でも変わりません。



原因は str3[1],str3[2] ...と範囲外に書き込んだことです。
例えるなら、「子供に紙とクレヨン渡したら、調子にのって床にまで絵を描いてしまった」状態です。
よって、対策は
・これらに書きこまないようにする。つまり、配列に収まる大きさの文字列にする
 (例えるなら「紙の外に描かないような小さな絵にする」)
・これらが書き込まれても問題ない状態にする。つまり、配列の大きさを十分に大きくする
 (例えるなら「絵が入るくらいの大きな紙にする」)
のどちらか、となります。

今回の場合、書き込みたい文字列が決まっているので、前者の「収まる文字列にする」という方法は使えません。
よって、後者の「文字列が収まる配列にする」が正解になります。

配列の大きさの指定方法はわかりますね?

一つ訂正します
誤) char str1[4]={"big"},str2[4]={"city"}, str3[1]={0};
正) char str1[4]={"big"},str2[5]={"city"}, str3[1]={0};

ベテランでもこういう単純な間違いをすることがあります。
間違えもいいんです。それに気付いて直せれば。

ダメなときは、どこでダメになっているかを調べ、何故ダメになるかを調べ、どうすればダメじゃなくなるかを考えます。
これはベテランでも初心者でも変わりません。



原因は str3[1],str3[2] ...と範囲外に書き込んだことです。
例えるなら、「子供に紙とクレヨン渡...続きを読む

Q最も高い身長を表示するプログラム

5人分の身長から最も高い身長を表示するプログラムをつくったのですが、エラーがでて実行できません。改善すべきところを教えてください。お願いします。
int main(void)
{
double a[5], max = 0;
int i;

for (i = 1; i <= 5; i++)
{
a[i] = 0;
}
printf("数値を5つ入力してください。\n");

for (i = 1; i <= 5; i++)
{
scanf("%lf", &a[i]);
}

for (i = 1; i <= 5; i++)
{
if (a[i] > max)
max = a[i];
}

printf("最も高い身長は%fです\n", max);

return 0;
}

Aベストアンサー

double a[5] ;
と宣言したら、安全に使えるのは a[0] 〜 a[4] です。

なので、このプログラムを安全なものにするなら
・double a[5]はそのまま、 i=0;i<5;i++ にして、 i=0〜4 の範囲で使う
・「i = 1; i <= 5; i++は変えない」 のなら
 ・ i=1〜5を、 0〜4 に対応させて使う
   単純明快なのは、 a[i-1] とすること
 ・double a[5+1] と宣言して、a[5] を安全に使えるようにする。
   a[0] が無駄になるけど気にしない

Q購入したDVDを再生しようとしたらリージョンコードエラーと出て見れませんでした 何か対策はありますか

購入したDVDを再生しようとしたらリージョンコードエラーと出て見れませんでした

何か対策はありますか?

Aベストアンサー

日本のリージョンコード「2」に設定されているDVDドライブに、例えばアメリカ国内で購入したリージョンコード「1」のディスクを入れるとリージョンコードが一致しないので、ドライブのリージョンコードの変更を促す画面が出ることもあります。「OK」で「1」に変更するとその後日本のリージョンコード「2」のDVDが再生されなくなります。(5回まで変更可)

「DVDのリージョンコードの制限を解除できるフリーソフト」
http://freesoft.tvbok.com/freesoft/player/dvd_region.html

DVDがPAL方式ならパソコンで見れるはず。
NTSC方式:日本、米国、カナダ、東南アジア
SECAM方式:フランス、東ヨーロッパ、中東、アフリカ
PAL方式:西ヨーロッパ、中国、アフリカ、中南米、オーストラリア

Q下記プログラムのフローチャート作りたいのですが、全く分からず教えてください。

const int BUTTON=13;
int val=0;
int old_val=0;
int state=0;

void setup(){
 for(int i=1;i<8i++){
pinMode(i,OUTPUT);
}
pinMode(BUTTON,INPUT);
}
boolean Num_Arrayt[10][7]={
0{1,1,1,1,1,1,0}
1{0,1,1,0,0,0,0}
2{1,1,0,1,1,0,1}
3{1,1,1,1,0,0,1}
4{0,1,1,0,0,1,1}
5{1,0,1,1,0,1,1}
6{1,0,1,1,1,1,1}
7{1,1,1,0,0,1,0}
8{1,1,1,1,1,1,1}
9{1,1,1,1,0,1,1}
}

void NumPrint(int Number){
for(int W=0;W <7;W++){
digitalWrite(W+1,Num_Array[Number][W]);
}
}
void loop(){
 val=digitalRead(BUTTON);
NumPrint(state);

if((val==HIGH)&&(old_val==LOW)) {

state=(state+1)%10;
NumPrint(state);
delay(300);
}
delay(100);
old_val=val;
}

const int BUTTON=13;
int val=0;
int old_val=0;
int state=0;

void setup(){
 for(int i=1;i<8i++){
pinMode(i,OUTPUT);
}
pinMode(BUTTON,INPUT);
}
boolean Num_Arrayt[10][7]={
0{1,1,1,1,1,1,0}
1{0,1,1,0,0,0,0}
2{1,1,0,1,1,0,1}
3{1,1,1,1,0,0,1}
4{0,1,1,0,0,1,1}
5{1,0,1,1,0,1,1}
6{1,0,1,1,1,1,1}
7{1,1,1,0,0,1,0}
8{1,1,1,1,1,1,1}
9{1,1,1,1,0,1,1}
}

void NumPrint(int Number){
for(int W=0;W <7;W++){
digitalWrite(W+1,Num_Array[Number][W]);
}
}
void loo...続きを読む

Aベストアンサー

ボタンがLOWからHIGHに変化した時点で7セグメントカウンタ表示の数字をカウントアップするというプログラムのつもりですね。

何がやりたいのかは薄々わかりますが、
 ちゃんと動く、エラーの出ないソースリスト
を書いてから質問してください。

QLinuxでのシリアル通信についてですが、受信のときにデータがずれた状態で送られてくることがあります

Linuxでのシリアル通信についてですが、受信のときにデータがずれた状態で送られてくることがあります。

例えば、正常なデータが以下のような場合
rtc[0] = 7
rtc[1] = 83
rtc[2] = 0
rtc[3] = 4
rtc[4] = 5


たまに
rtc[0] = 0
rtc[1] = 7
rtc[2] = 83
rtc[3] = 0
rtc[4] = 4


rtc[0] = 0
rtc[1] = 0
rtc[2] = 7
rtc[3] = 83
rtc[4] = 0


rtc[0] = 83
rtc[1] = 0
rtc[2] = 4
rtc[3] = 5
rtc[4] = 0


といった結果になります。

プログラムでは、7バイト分読み込む場合は

unsigned char buff[7];



int r = read(fd, buff, 7);


と書いています。何か問題があるでしょうか。
宜しくお願いします。

Aベストアンサー

今時、シリアルポートの通信プログラムを書いている人がいるんですね、、懐かしいです。
データ化けしているわけでは無いのでビットレベルの同期はできているようです。
次に同期が必要になるのはブロック単位の同期ですが、これができていない状況です。
read() で読む際には期待する位置に格納(受信)されている保証はありません。
シリアル通信の場合は1バイトづつ読みながら目印になるバイト列が来たらそれからデータが始まると判断をする必要があります。

Qc言語

c言語って本読んで勉強してもどこに保存するのかわかりません。
メモ帳で拡張子.cで保存すればいいのでしょうか
初歩的ですいませんがお願い致します

Aベストアンサー

Cのプログラムの作成とコンパイルの手順
http://guppy.eng.kagawa-u.ac.jp/~kagawa/2011/Programming1/dosPrompt.html

で紹介されている、bcc32というボーランド社製のコンパイラは現在、

プログラムの作成
C++ Compiler - FREE TOOL
https://www.embarcadero.com/jp/free-tools/ccompiler/start-for-free

になっていると思います。

Borland C++ Compilerのダウンロードとインストール - Windows環境
http://webkaru.net/clang/borland-c-compiler-install/

Borland C++ Compilerの設定 - Windows環境
http://webkaru.net/clang/borland-c-compiler-how-to-use/

を見てコンパイラのパスを設定すれば、
フォルダに保存した拡張子cなどのファイルをコンパイル出来るようになります。

Cのプログラムの作成とコンパイルの手順
http://guppy.eng.kagawa-u.ac.jp/~kagawa/2011/Programming1/dosPrompt.html

で紹介されている、bcc32というボーランド社製のコンパイラは現在、

プログラムの作成
C++ Compiler - FREE TOOL
https://www.embarcadero.com/jp/free-tools/ccompiler/start-for-free

になっていると思います。

Borland C++ Compilerのダウンロードとインストール - Windows環境
http://webkaru.net/clang/borland-c-compiler-install/

Borland C++ Compilerの設定 - Windows環境
http:/...続きを読む

QC言語 構造体の中に共用体を定義した変数の初期化に関して

C言語のコンパイルエラーに関する質問です。
以下のような構造体の中に共用体を作成して、constで初期値を入れておきたいと考えています。
機械に適用する初期パラメータのような感じです。
「初期化子が多すぎます。」というコンパイルエラーがでるのですが、どこが多いのかわかりません。
どう修正すれば良のか教えていただけないでしょうか?

// 構造体定義
typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t xxxx;
Uint16_t zzzz;
}PrgPatternA_t;

typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t yyyy;
}PrgPatternB_t;

typedef struct {
Uint8_t pattern;
union {
PrgPatternA_t param_a[3];
PrgPatternB_t param_b[2];
}param;
} Program_t;

// 変数定義
EsCourseProgram_t ES_COURSE_PROG_DATA = {
PATTERN_A,
{ // Aパターン
// time mode xxxx yyyy
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50}
}
}

C言語のコンパイルエラーに関する質問です。
以下のような構造体の中に共用体を作成して、constで初期値を入れておきたいと考えています。
機械に適用する初期パラメータのような感じです。
「初期化子が多すぎます。」というコンパイルエラーがでるのですが、どこが多いのかわかりません。
どう修正すれば良のか教えていただけないでしょうか?

// 構造体定義
typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t xxxx;
Uint16_t zzzz;
}PrgPatternA_t;

typedef struct {
Uint16_t ti...続きを読む

Aベストアンサー

どの初期値がどのメンバーに対応するかをじっと見ていくと, {} が 1つ足らない. つまり初期化子は
{
PATTERN_A,
{ // Aパターン
// time mode xxxx yyyy
{
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50}
}
}
}
でないといけない.

どこかの {} を忘れていたんだと思う. 共用体を初期化するときの {} かなぁ?

Qarduino

arduinoって同時にプログラム実行できないんでしょうか。例えばシリアル通信中にLチカをして通信状態確認するとか。回答よろしくお願いします。

Aベストアンサー

>arduinoって同時にプログラム実行できないんでしょうか。

できません。
ちなみにマルチコアなどでない限りPCでも同時に実行できるのは1つの命令が基本です。
# 最近はマルチコアも普通になってきていますが。

>例えばシリアル通信中にLチカをして通信状態確認するとか。

処理を細切れにして実行するようにスケッチを作成すれば可能です。

シリアルの受信バッファにデータがあったら1文字(1Byte)読み込んで配列に格納。なかったら次の処理へ。
時間を取得して、前回のLED点灯(または消灯)から一定時間過ぎていたらLEDを消灯(または点灯)。
シリアルからの受信データがある程度貯まったら内容判定して必要な処理を実行、

というかんじでループ中に細切れに処理していきます。
# シリアル送信も1ループ中に1文字(1Byte)だけ送信。とか。

QArduinoでターミナル等に触ると誤動作する

Arduino Unoで図のような回路を組んでいます。
なぜか矢印のターミナルに触るとその先のスイッチがONになったと勘違いした動作をします。
なぜこのようになってしまうかと対策など、ご存知の方に教えていただけたらとおもいます。

最初はこの回路でなく、内蔵プルアップにしました(その時は4.7kΩは無かった)。内臓プルアップでこれと同じ誤動作が起きたのでそれを止めてこの形になりました。

ターミナルに触ると言うのはドライバの先やテスターのプローブの片方だけが触れると言う意味です。それは手持ちで、身体やその物のどこか一部が別の場所に触れていると言う事はありません。

図は、実際の基板のレイアウトとほぼ同じです。ターミナルの列から上はユニバーサル基板に乗っていて半田付けされています。Arduinoの電源はUSB経由です。

Aベストアンサー

回答NO.2です。
 すみません、回路でLEDの抵抗3本の共通ラインはGNDにつながってたのを見落としてました。
回路図を書き直して添付しました。この回路でそういう現象が起きるという事はAC電源の誘導電圧が大きいとしか考えられませんので添付図のように電解コンデンサC1とC2(それぞれ10uF/10V)を追加すれば誤動作はなくなると思います。


人気Q&Aランキング