C言語で指定アドレスにジャンプさせる方法は?

このQ&Aのポイント
  • C言語でルネサス製RX62Nを使ったマイコンボードにおいて、指定したアドレスにジャンプさせる方法を教えてください。
  • 変数Aに格納した値をアドレスとして扱い、そこにジャンプさせる方法を知りたいです。
  • 以前、0x20000000番地にジャンプする方法を知りましたが、自分で計算したアドレスにジャンプさせる方法が分かりません。アドバイスください。
回答を見る
  • ベストアンサー

指定アドレスにジャンプさせたい場合【C言語】

こんにちわ。 この度、初めてOK Waveから質問させて頂きます。どうぞ宜しくお願い致します。 現在、ルネサス製RX62Nを使ったマイコンボードを使用して、C言語によりプログラムを組んで様々な動作をさせているのですが、「RX62N内部のFlashROMの指定したアドレスにジャンプさせる方法」がうまくいかず、どなたか良い方法を教えて頂きたいと思います。 具体的には、変数Aに格納した値(32bit)をアドレスとして扱い、そのアドレスにジャンプしたいと考えています。 以前、他のかたの質問の回答で、  typedef void (*FN_PROGRAM)(void);  FN_PROGRAM pg = (FN_PROGRAM)0x20000000;  (*pg)(); という記述方法で20000000番地にジャンプできると記載があったため、早速、アドレスを0xFFFC0000に変更して動作させてみたところ、0xFFFC0000番地にジャンプさせる事ができ、大いに役に立ちました。 今回、私の方では、始めから0xFFFC0000番地と決め打ちせず、色々と計算をした後、最終的に決まったアドレスを変数Aに格納し、その格納した値をアドレスとして扱い、そこにジャンプさせる方法をとりたいと考えています。 お手数ですが、上記方法で、良い記述方法があればアドバイス頂けないでしょうか。できれば、使う変数Aの宣言文から教えて頂けると有難いと考えています。 説明が下手で申し訳ありません。C言語初心者ですので皆さまから色々とアドバイス頂けると助かります。よろしくお願い致します。、

質問者が選んだベストアンサー

  • ベストアンサー
  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.1

手元に実行確認できる環境がないので、下記方法で試してみてください。 要は、計算結果を関数のエントリーアドレスにキャストしてしまえば良いだけだと思います。 なので、 unsigned long func_adr; などを定義して、飛ばすべきアドレスを計算し、以前の方が教えていただいた様なキャストを使って、 FN_PROGRAM pg = (FN_PROGRAM)func_adr; で、pgに関数の計算したエントリーアドレスを渡してあげれば出来ると思います。 ただし、アドレス計算で予期しない計算結果になった時に、確実に暴走しますので、 FN_PROGRAM pg[] = { … と、関数のエントリポイントの配列を定義し、予め用意されているライブラリ分だけ、アドレスを登録しておいて、計算結果によって引数が決まる様な方法もあります。 面倒くさかったら、計算結果をswitch分で分岐させて、計算結果に応じた関数(予めエントリーアドレスを定義した関数名。ライブラリ分全部定義しておく。)に飛ばしてしまう、という方法もあります。多分、これが一番Debugが楽、かつ、コードが読みやすいのではないかと思います。 ご参考に。

sugato
質問者

お礼

KEIS050162さん、早速のご回答ありがとうございました。 アドバイス頂いた、「unsigned long func_adr」で宣言しておいて「FN_PROGRAM pg = (FN_PROGRAM)func_adr;」と書き換える方法で、計算して求めたアドレスに無事ジャンプする事ができました。 最初、「typedef void (*FN_PROGRAM)(void);」と「FN_PROGRAM pg = (FN_PROGRAM)func_adr;」の2行を、関数に入る前の宣言文のところに記述していたため、コンパイルエラーが発生しましたが、この2行を関数の中に記述するようにしたところエラーがなくなり、func_addrに格納しておいたアドレスへジャンプする事ができました。 この度はアドバイス頂き大変たすかりました。有難うございました。C言語の初心者なので今後も何かと質問を載せる事があるかと思いますが、今後もしご覧になられる機会があればぜひアドバイスのほどよろしくお願いします。

関連するQ&A

  • C言語でのエラーの直し方について?

    C言語でのエラーが発生したとします。その時、どのようにして、エラーを見つけ直していくのですか? 私はprintfを用いて値を見ることでエラーを見つけています。 ステップインで実行して変数にどのような値が入っているか見つけようともしているのですが、変数にa値が16進数で格納されていたり、アドレスがあったりと見方が複雑でうまく発見できていません。 正しい、エラーの見つけ方、直し方とはどういったやり方なのでしょうか?

  • C言語の問題です!!

    C言語の問題です。よろしくお願いします。 A: 次の手順で処理を行うプログラムを作成しなさい. ・int型の変数n1,n2に数値9,3を代入する. ・変数n1,n2の値を"n1=xxx, n2=xxx"のように表示する. ・変数n1の値をn2倍にし,変数n2の値に2を加算する. ・変数n1,n2の値を表示する. ・変数n1とn2の互いの値を入れ替える. ・変数n1,n2の値を表示する. B: 本日の為替相場は,80円/ドル(int型の変数rate_dに格納)と114円/ユーロ(rate_e)である. ドル(usd)を与えて,ユーロ(euro)に変換するプログラムを作成せよ. ただし,小数点以下は切り捨てとする.

  • C言語におけるローカル変数が使用するメモリについて

    例のようなC言語のプログラムを動かした場合、 確保されるメモリ領域はどうなるのでしょうか。 例 #include <stdio.h> int main(void) { int a = 0; } このとき、変数aはint型なのでスタック領域に4バイトのメモリが確保されると理解しています。 と同時にaという変数名と確保されたスタック領域の番地を紐づけるようなメモリがどこかに確保されるのではないかと思ってるのですが、この理解で正しいでしょうか。 またその場合は変数aの番地はどの領域に確保されるのでしょうか。 ご教示お願いいたします。

  • c言語で定義する変数のアドレス

    c言語の超初心者です。追いえてください。 c言語で2つの変数を定義しています。 char *a; char *b; この2つの変数に値をいれた際の動作で以下のようなことって発生しますか? a="1111" b="2222" aをprintfするとbにいれた値"2222"が表示される。

  • アドレス指定方式での、命令語が参照する番地

    16進数で”C13B0206”という32ビットの命令語があります。 <命令語の仕様> 0~7ビット:命令指示部 8~10ビット:レジスタ 11~15ビット:アドレス修飾部 16~31ビット:番地 <アドレス修飾と参照番地の関係> 00 0固定 直接アドレス (11,12の値が00、13~15の値が0固定のとき、直接アドレス。) 01 0固定 間接アドレス 10 インデックスレジスタ インデックスレジスタ+番地の値 11 インデックスレジスタ インデックスレジスタ+番地が示す内容の値 <主記憶、レジスタの状態> ●主記憶に格納されている値(16進数) 番地(16進数)が  202,203,204,205,206,208,209,20A...の順に、それぞれの格納値は、 203,204,205,206,208,209,20A,20B...。 ●インデックスレジスタに格納されている値(16進数) インデックスレジスタ番号(16進数)が1,2,3,4,5… の順に、それぞれの格納値は、 0,1,2,3,4…。 (1) アドレス修飾部のインデックスレジスタ番号。 命令語の”C13B0206”で、アドレス修飾部にあたるのが”3B”。00111011(2進数)。8~10ビットの001がレジスタになるから、3。 (2)命令の番地部の番地の値(16進数) 命令の番地部の番地の値。命令部では、”0206”。ちょうど16進数なので、206。 (3) 命令が最終的に参照する番地。 上の、<主記憶、レジスタの状態>より、11~15ビットが”1011”。 インデックス番号が11(2進数)なので、3(16進数)。インデックスレジスタ番号が3のとき、格納されているのは2。番地の値である206と3を合わせ、209。 最終的に参照される番地は209。 (1)(2)(3)、自分の解き方が正しいのかどうか自信がありません。どなたか補足、訂正などありましたら、よろしくお願いいたします。

  • PIC C言語でコード開始アドレスを指定する方法

    PIC18F2550用にMPLAB-IDEでC18コンパイラを使って、作ったファイルをUSB経由でブートしようとしています。下位番地にはブートローダが入っているため、プログラムの開始アドレスを800番地以降におきたいのですが、例えばアセンブラ言語のORG命令のようにコードの開始番地を指定することはできないでしょうか?

  • [C言語]変数のアドレスを直接指定する構文

    C言語でのマイコン開発環境に付属しているヘッダーファイルにはレジスタを共用体と構造体でアクセスできるようにしてあります。 アドレスを割り付ける部分の記述は一行ですが、意味を考えた時に構文が複雑すぎて躓いてしまいました。 #define PD (*(volatile struct st_pd *)0xFFFF83A0) /* PD Address*/ 後ろの"*"はst_pdのポインタ型だとして前の"*"はどういう効果になっているのでしょうか? また、複数行に分解して同じ効果を書くこと(例えば変数unsigned long valにアドレス0xFFFF83A0を割り付け)は出来るのでしょうか? 理解を助けるためにお願いします。

  • C言語の変数について

    C言語の変数について教えていただきたいです。 C言語で下記のような設定をした場合、変数A、Bに設定する値にはバイト数制限 はないのでしょうか? バイト数制限がなくなる場合、なぜそうなるのかを教えていただきたいです。 よろしくお願いします。 #include <stdio.h> void test( char **B); int main( int argc, char *argv[] ) { char *A = NULL; char *B = NULL; A = argv[1]; test( B ); return 0; } void test( char **B ) { strcpy(B, "ABCD"); return 0; }

  • C言語のポインタについての質問です。

    C言語のポインタについての質問です。 2つのプログラムを作り、片方で数値を入力し、 もう片方でその数値を読み取りたいと思っています。 数値入力のプログラムは次のようになっています。 #include<stdio.h> void main(void){ int A=1; int *p; p=&A; printf("%p\n",p); } この実行結果は「0012FF88」となりました。 次にこの「0012FF88」というアドレスを使って「1」を読み取る 別のプログラムを作りたいと思っています。 #include<stdio.h> void main(void) { int add; int a; printf("アドレスは?\n"); scanf("%x",&add);    //「0012FF88」と入力 a=*(int*)add; printf("%x---->%d",&add,a); } このようなプログラムを作ってコンパイルできたのですが、 実行してアドレスを打ち込むと「Win32の例外が発生しました」 となって実行できません。 何かよい方法やプログラムの問題などありましたら 教えて頂けませんか?

  • エクセルのMID関数は、C言語では?

    最近C言語を始めたものです。 エクセルでは文字列の3文字目~5文字目を切り取る際に MID("文字列",3,2) と記述できますが、C言語の場合、はどのような記述方法になりますか?ご教授お願いいたします。 いま悩んでるのが、CHAR型の変数:aaaに"abcdefghi"を格納して、 aaaの3文字目~7文字目を抜き出したいというC言語での方法です。

専門家に質問してみよう