皆さん、有難う御座います。時々質問させて頂いています。

 今回は、ベクターアドレスをC言語で書く方法について質問します。
 ルネサスのH8マイコンを使っています。モニターを使うとRAM上に割り込みの仮想ベクターを作れます。
 仮想ベクターには、割り込みのジャンプ先アドレスが書かれます。
 現在アセンブラで書いているのですが、C言語で書く方法は無いでしょうか。
 二つの方法で書きたいと思っています。
 アセンブラで次の二つの方法に相当するC言語命令を知りたい。

(1)ORGとEQU命令を使った方法
(2)ムーブ(Z80ならロード)命令で関数のアドレスをメモリに書く方法

 ルネサスにはHEWと言うソフトが有りますが、HEW特有の命令によらず、一般的なコンパイラが持っている機能で実現したい。

 以上宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (19件中1~10件)

> *(void **)(0xFE130) = &test ;



コンパイラに依存しないという意味では、上記の方法は問題があります。
CPUアドレスをポインタにキャストしても、期待した結果になるかどうかは保証されないからです。
ただ、通常はこれで問題なく動作するでしょうが...

> 関数のアドレスを書き込む方法が分からないと配列に出来ません。

これは、

void vector00();
void vector01();
...

void (* const vectors[])() = {
 &vector00,
 &vector01,
 ...
};

のようにすれば、配列にできます。
    • good
    • 0
この回答へのお礼

 回答有難う御座いました。

 この方法で配列に出来ました。
 残る課題はセクション指定です。
 No.4, No.5 さんの回答にその方法が書いてあると思うのですが、自分の能力不足のためまだ良く分かりません。
 これから調べようとしています。

 また何か有りましたら、宜しくお願いします。

お礼日時:2009/05/24 19:08

>モニターは、ROM上のプログラムだって動かせます。


>仮想ベクタはRAM上に有ります。
>モニタとユーザが作ったプログラム両方をROMに置けます。
>モニタをそのまま使用するなら、Gコマンドでユーザプログラムを実行すれば良い。
>モニタを改造すれば、リセットスタートでユーザプログラムに飛ばす事も可能です。

そこまでしますか。
プロなら有り得ませんが、アマチュアならまぁやりたければどうぞ。
そもそも仮想ベクタがどうやって実現しているか分かってます?
表面上見えませんが、割り込み処理時に一度モニタに飛んでから更に仮想ベクタを参照して再ジャンプする仕組みになってるんで時間ロスが発生します。
それにRAM上にベクタがあることでメモリ破壊暴走の危険が増します。これもプロとしては許せません。

R32Cさんの書いているベクタの設定もそうですが、モニタを前提とした設計は無駄なことをしていると思います。
    • good
    • 0
この回答へのお礼

 色々有難う御座います。

 私の知りたかった事は、回答番号No5に有る様に解決しました。
 この辺で締めませんか。

 ここは人気が有って、C言語の質問があっと言う間に増えます。
 私の方はもう解決したので、他の方の質問の回答に時間を使って頂きたいと思います。

 また何か質問した時は、宜しくお願いします。

お礼日時:2009/05/31 08:06

単純に、ベクタアドレスを設定する部分だけ、アセンブリ言語のソースとして


分割すればいいだけの話のように思います。
それが、Cなのかアセンブリ言語なのか、どちらでも保守性は変わらないと
思います。どちらかというとリンカの指定を省いてアドレス指定ができる
アセンブリ言語で書いたほうが保守しやすいとは思いますが
    • good
    • 0
この回答へのお礼

 色々有難う御座います。

 私の知りたかった事は、回答番号No5に有る様に解決しました。
 この辺で締めませんか。

 ここは人気が有って、C言語の質問があっと言う間に増えます。
 私の方はもう解決したので、他の方の質問の回答に時間を使って頂きたいと思います。

 また何か質問した時は、宜しくお願いします。

お礼日時:2009/05/31 08:06

同じこととしか思えないですね。



>しかし割り込みを使うと、START_Cを個別に変更しアセンブル
>し直さなければ成りません。
>C言語だけで記述出来れば、START_Cの変更が入らなくなります。

C言語だけで記述できても、C言語で記述するベクターテーブルはコンパイル
しなおさないといけないので同じですね。

補足要求の意味がわからなかったのでしょうか?
    • good
    • 0

>H8/3052だけです。

プログラムによって割り込みを使ったり使わなかったりすると、
>アセンブラのベクターテーブルをその都度変更しなければなりません。
> C言語で処理できれば、アセンブラ部分は変更しないで共通に使えます。

???
なんかおかしくありませんか?

Cで書こうとアセンブリ言語で書こうと、ベクタテーブルの変更が必要なら
どちらの言語でも変更が必要ですよね。
確かに、
Cで書けば当然Cで変更が必要で、おっしゃるとおりアセンブリ言語の変更は不要ですが
いったいどのような仕組みをお考えなんですか?
    • good
    • 0
この回答へのお礼

 スタックポインタの設定など行うSTART_Cと言うアセンブラ・プログラムが有ります。その中で仮想ベクタの設定を行っています。
 不意な割り込みが入ってもいいように、無限ループプログラムのベクタを入れて有ります。

 割り込みを使わないC言語プログラムなら、START_Cはどれにでも使えます。

 しかし割り込みを使うと、START_Cを個別に変更しアセンブルし直さなければ成りません。

 C言語だけで記述出来れば、START_Cの変更が入らなくなります。

お礼日時:2009/05/29 23:30

> ルネサスで無料で提供しているモニタが有ります。

 割り込みが入るとモニタに入り、そこからRAMに書いた仮想ベクタのアドレスに飛ぶようになっています。

えーと。伝わっていないかな?
全部のプログラムをROM化して、それをモニタから動かす気ですか?
モニタが動かすプログラムってRAM上だし、ベクタもRAM上ですよね。ここで言うROM化とは、ROMに全て焼く&ベクタもROMにあるモニタもない状況です。
最終的にプログラムをROM化せずRAM上でモニタで動かす実験だけの予定であれば今の方針のままで良いですがそのつもりですかと伺っています。回答番号:No.2からROM化とは、そのつもりで言ってました。
    • good
    • 0
この回答へのお礼

>モニタが動かすプログラムってRAM上だし、ベクタもRAM上ですよね。

 モニターは、ROM上のプログラムだって動かせます。
 仮想ベクタはRAM上に有ります。

>ここで言うROM化とは、ROMに全て焼く&ベクタもROMにあるモニタもない状況です。

 モニタとユーザが作ったプログラム両方をROMに置けます。
 モニタをそのまま使用するなら、Gコマンドでユーザプログラムを実行すれば良い。
 モニタを改造すれば、リセットスタートでユーザプログラムに飛ばす事も可能です。

お礼日時:2009/05/29 23:40

>1.RAM上で開発してROMに書き込みます。


> printf()などは大きくてRAMに収まりません。
> ROMに書いて、呼び出す実験をした事があります。
>  コンパイル後にROMに書き、EQU命令で関数のアドレスを定義し、C言語で呼び出しました。

前にも書きましたがベクタを含めてROM化する場合は今のベクタをプログラムで書き換える方法は使えません。ROMですからね。そこの所はどう考えてますか?
    • good
    • 0
この回答へのお礼

 ルネサスで無料で提供しているモニタが有ります。
 割り込みが入るとモニタに入り、そこからRAMに書いた仮想ベクタのアドレスに飛ぶようになっています。

お礼日時:2009/05/28 21:54

richardoさん、はっきりしていないので答えてください。


1.RAMで使う前提である。ROMは考えていない。
2.H8限定。
3.H8アドバンストモード専用
4.C言語だけで全てを行いたい。アセンブラやリンカ・スクリプトでは何もしない。
って事ですよね?
    • good
    • 0
この回答へのお礼

 zwiさん、

1.RAM上で開発してROMに書き込みます。
 printf()などは大きくてRAMに収まりません。
 ROMに書いて、呼び出す実験をした事があります。
  コンパイル後にROMに書き、EQU命令で関数のアドレスを定義し、C言語で呼び出しました。

2.H8/3052用です。

3.そうです。アドバンストモードです。

4.C言語で対処出来るなら、C言語でやりたいという事です。

 今までの結果は、回答番号5の「お礼」に書いた通りです。
 

お礼日時:2009/05/27 23:16

> ヘッダ・ファイルは共通に使えるようになっていますよね。


> それと同様にC言語に伴うアセンブラ・ソフト部分も変更せず、
>C言語部分の変更だけで対処出来ないかなという事です。
???
どれだけのCPUで共通部品にしようとしているのですか?
少なくとも、ベクターテーブルを持たないCPUでは使えないことは
お分かりですよね?
    • good
    • 0
この回答へのお礼

 R32Cさん、

>どれだけのCPUで共通部品にしようとしているのですか?

 H8/3052だけです。プログラムによって割り込みを使ったり使わなかったりすると、アセンブラのベクターテーブルをその都度変更しなければなりません。
 C言語で処理できれば、アセンブラ部分は変更しないで共通に使えます。

お礼日時:2009/05/27 22:46

>でも私の質問は、「アセンブラなら実現方法が分かるけど、C言語で実現する方法を知りたい」という事です。


gccとかHEWのCコンパイラは重いから使いたくないって事ですね。しかし、そうするとセクションはC38H.EXEだと機能的に操れない可能性が高い状況ですから無理があります。C38H.EXEを自分で改造しますかって話ですね。
その貫き通したい気持ちは好きですが、そこまでやる気がありますか?
    • good
    • 0
この回答へのお礼

>C38H.EXEを自分で改造しますかって話ですね。

 そんな事はしません。私の知りたかったのは、関数のアドレスを得る方法です。アスタリスクを上手に使うと得られるみたいだけど、その方法が分からなかったのです。
 回答番号5のお礼に書いてある様に、その方法は分かりました。
 有難う御座いました。

お礼日時:2009/05/28 22:12

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

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

QC言語のポインタに直接アドレスを割り振りしたい

C言語のポインタに直接アドレスを割り振りしたいのですが、どうしたら良いのでしょうか?

Aベストアンサー

直接アドレスを割り振りたい、というのは
int* pnValue;
pnValue = (int*)0x12345678
ということでしょうか?このようにすればポインタにアドレスを代入することはできるかと思います。

Qマイコン C言語 割り込み処理で変数参照

マイコンのC言語で1つ困っています。

メイン処理である条件でグローバル変数Aを設定しています。

また、割り込み処理をタイマーとして使い、グローバル変数Aを参照しています。

このような動作の時に割り込み処理でグローバル変数Aを参照した際にエラーで動作しなくなります。

おそらく、同じデータをメイン処理での設定と割り込み処理での参照を行ったせいだと思いますが、

何かPICプログラミングとして最適な対処法はありますか?

是非、ご教授お願いします。

Aベストアンサー

まず、エラーが出たなら、どういうエラーなのかを明確に記載して下さい。
それから、セマフォ・mutexという言葉が出てきていますが、
割り込みハンドラ中で、待ちが発生する処理を記載してはいけません。
可能な限り短く処理を終わらせなければなりません。

割り込みは、高い優先度をもって実行されていますから、待ち状態を作ってしまうような処理を
書いてしまうと、他の割り込み制御に影響を及ぼしたり、待ち状態解除を行う側のタスクが
動作できなくて、デッドロックすることがあります。

割り込みハンドラの中で、printfでログを出力することなども、禁止です。
printfの中には、ストリームバッファの排他制御があるので、待ち状態になる可能性が
あるためです。

基本的には、割り込みハンドラ内では、最短で処理を終わらせるために、
フラグをONするような処理しかしてはいけません。
そして、メインスレッドでフラグがONなら処理をするような形とします。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

QRS232C 調歩同期のビットレート誤差について

RS232C 調歩同期のビットレート誤差は何%程度まで許容できるのでしょうか?
また、目安とその理由について教えて下さい。

SH4のプログラムを組んでいます。
例えば、パソコンとRS232C(調歩同期)通信を行う際のビットレートの設定で、SH4側のビットレート誤差は何%以内にするべきでしょうか?
クロック同期の場合は、「なるべく1%以内になるように」とマニュアルに記載があるのですが。。。

Aベストアンサー

まずは
データ長8ビット
パリティなし
ストップビット1

だとすると、シリアルデータは全部で10ビットです。

スタートビットから同期し、各ビットの中央でデータをサンプリングするなら、10番目のビットが50%以上ずれるとアウトです。つまり5%誤差ですね。

しかし世の中そううまくいきません。コントロールICによって違いますが、ビットレートの8倍や16倍で各データをサンプリングします。1ビットを8回や16回チェックしてるんですね。

ビットがHかLかを判断するのもいろいろですが、中央部数回分(8回サンプルなら3~4回程度)を多数決原理で判断するのが多いようです。とすると、せいぜい2.5%となります。

これに、クロック源の誤差も加味すると2%くらいが限度です。



CPUクロックからビットレートを生成する場合、ビットレートにあわせた変な周波数のクロック源でなければ0%なんて無理ですよね。実際は1%以内なら気にしませんし、大丈夫ですよ。

Qエクセルで計算すると2.43E-19などと表示される。Eとは何ですか?

よろしくお願いします。
エクセルの回帰分析をすると有意水準で2.43E-19などと表示されますが
Eとは何でしょうか?

また、回帰分析の数字の意味が良く分からないのですが、
皆さんは独学されましたか?それとも講座などをうけたのでしょうか?

回帰分析でR2(決定係数)しかみていないのですが
どうすれば回帰分析が分かるようになるのでしょうか?
本を読んだのですがいまいち難しくて分かりません。
教えてください。
よろしくお願いします。

Aベストアンサー

★回答
・最初に『回帰分析』をここで説明するのは少し大変なので『E』のみ説明します。
・回答者 No.1 ~ No.3 さんと同じく『指数表記』の『Exponent』ですよ。
・『指数』って分かりますか?
・10→1.0E+1(1.0×10の1乗)→×10倍
・100→1.0E+2(1.0×10の2乗)→×100倍
・1000→1.0E+3(1.0×10の3乗)→×1000倍
・0.1→1.0E-1(1.0×1/10の1乗)→×1/10倍→÷10
・0.01→1.0E-2(1.0×1/10の2乗)→×1/100倍→÷100
・0.001→1.0E-3(1.0×1/10の3乗)→×1/1000倍→÷1000
・になります。ようするに 10 を n 乗すると元の数字になるための指数表記のことですよ。
・よって、『2.43E-19』とは?
 2.43×1/(10の19乗)で、
 2.43×1/10000000000000000000となり、
 2.43×0.0000000000000000001だから、
 0.000000000000000000243という数値を意味します。

補足:
・E+数値は 10、100、1000 という大きい数を表します。
・E-数値は 0.1、0.01、0.001 という小さい数を表します。
・数学では『2.43×10』の次に、小さい数字で上に『19』と表示します。→http://ja.wikipedia.org/wiki/%E6%8C%87%E6%95%B0%E8%A1%A8%E8%A8%98
・最後に『回帰分析』とは何?下の『参考URL』をどうぞ。→『数学』カテゴリで質問してみては?

参考URL:http://ja.wikipedia.org/wiki/%E5%9B%9E%E5%B8%B0%E5%88%86%E6%9E%90

★回答
・最初に『回帰分析』をここで説明するのは少し大変なので『E』のみ説明します。
・回答者 No.1 ~ No.3 さんと同じく『指数表記』の『Exponent』ですよ。
・『指数』って分かりますか?
・10→1.0E+1(1.0×10の1乗)→×10倍
・100→1.0E+2(1.0×10の2乗)→×100倍
・1000→1.0E+3(1.0×10の3乗)→×1000倍
・0.1→1.0E-1(1.0×1/10の1乗)→×1/10倍→÷10
・0.01→1.0E-2(1.0×1/10の2乗)→×1/100倍→÷100
・0.001→1.0E-3(1.0×1/10の3乗)→×1/1000倍→÷1000
・になります。ようするに 10 を n 乗すると元の数字になるた...続きを読む

QH8 マイコン セクションの設定について

最近H8/3694Fを使ってマイコンの勉強をしております。
HEWを使ってコンパイルするときのセクションの設定に
ついて質問があります。

プログラム・セクションの設定を一通り終え、ビルドすると
「L2321 (E) section "S" overlaps sction "P"」
とエラーメッセージが出てしまいました。

色々調べてみるとSはスタック領域、Pはプログラム領域
でこれに重なりができてしまっているようなのですが、
これ以上どうしてよいのかわからず困っています。

おそらくセクション設定を変更すればよいと思っていますが
プログラム領域にどれくらい、スタック領域にどれくらい
を配置すればいいというのはどうやって求めればよいのでしょう?
HEWのメモリマップを表示させて見る方法があるようですが
見てもいまいちわかりませんでした。

使用環境:OS:WindowsXP、HEW4.04.01.001

以上、追記補足いたします。詳しい方教えていただけないでしょうか

Aベストアンサー

実際のリンク結果のアドレスマップは、「Standard Toolchain」の最適化リンカのオプションを変更すれば出力できるはずです。
「リンクマップファイル」がキーワードでマニュアル等を探してみてください。うまく行けば、[プログラム名].mapの名前で作成されるはずです。

>「L2321 (E) section "S" overlaps sction "P"」
RAMで実行する設定にしたなら、このエラーも納得です。
プログラムが本当に大きすぎるんだと思います。
>0X0000FE80 S
となっていますので、設定を変えていないと0x100サイズのスタックが取られるらしいので、0xFD80-0xFE80はスタックになります。
プログラムの部分のPセクションが、0xFD80を超えてしまっていると思いますよ。

Qプログラム設計書の書き方

僕は新人SEです。
今、上司の方からあるシステムの基本設計書・システム設計書・プログラム設計書を作り、プログラミングまでしてから単体テスト・結合テストもやるように言われています。(全て1人で)

おそらく経験のある方ならすぐにできてしまうようなシステムで、上司の方も勉強のために全てやらせているようです。

今、基本設計書・システム設計書まではなんとかできて、プログラム設計書の作成に取り掛かりたいのですが、初めての経験で実際のプログラム設計書には何をどのように書いているものなのかも全く見当もつかずにいるので全く何も書けません。

上司さんは今週忙しいようで
「来週見てあげるから自分で調べたりしてやってみて」
と言っています。
ですが、全く何もできずにいるのもイヤなので何かそれらしいものでも書いてみたいのですが…プログラム設計書とは何をどう書いてあるものなのでしょうか?

日本語が書いてあるのかプログラムが書いてあるものなのか…
そういったところからわからないので少しでも何か教えていただきたいです。
宜しくお願いします。

Aベストアンサー

こんにちは。
No.1様のご回答通りなのですが会社によって異なります。
というのを踏まえた上で・・・うちではという回答になりますが

・日付 2009/10/10
・版 初版(その後バージョンアップで改定するため、改定ナンバー必須)
・タイトル 企業情報印刷(ここでは決定済み名称)
・発注仕様書ナンバー(正式にお客さまと契約で決めた発注番号を記載)
・作成者 boo_boo_suu
・使用言語 Visual C++
・使用データベース ORACLE
・使用帳票アプリケーション Crystal Reports
・フロー図(Visioで埋め込み図)
・概要説明 
メインメニューから呼び出され企業情報の印刷条件を入力し、クリスタルレポートの帳票情報から企業情報ファイル(KIGYOU_INFO)ファイルを呼び出し印字します。
・全企業情報が一覧で印字可能である。
・特定一企業(企業コード指定)での印字も可能である。
・一企業が指定された場合は企業情報を画面表示する。

-----------------------------------
で・・・・プログラム仕様書はこのくらい。
命令書ですからコードそのものは打ちません。
これみて作ってもらわないといけないので日本語メインです。

あとはDBの仕様書をみてもらったりしてプログラムのローカルルール、画面サイズ、文字サイズ プロシージャ定義やら定数や変数、フォーム、構造体定義書などプログラム書くときの決まりごとに添ってPGさんに打ってもらっています。
一応、図とかつけてみました。(^-^;;
全体の雰囲気はこんな感じだとご理解いただければ幸いです。
ではでは~。

こんにちは。
No.1様のご回答通りなのですが会社によって異なります。
というのを踏まえた上で・・・うちではという回答になりますが

・日付 2009/10/10
・版 初版(その後バージョンアップで改定するため、改定ナンバー必須)
・タイトル 企業情報印刷(ここでは決定済み名称)
・発注仕様書ナンバー(正式にお客さまと契約で決めた発注番号を記載)
・作成者 boo_boo_suu
・使用言語 Visual C++
・使用データベース ORACLE
・使用帳票アプリケーション Crystal Reports
・フロー図(Visioで...続きを読む

Q#if 1 #elseの意味について

#if 1
 文 
#else 
 文
#endif
という表記に関して、「#if 1」が「必ず有効」という事はわかるのですが、ここでの「#else」とは「1」でない時ということで、「#if 0」と同じ意味と考えていいのでしょうか?

Aベストアンサー

>「#if 0」と同じ意味
「#if~#endif」がすこーぷの範囲ですから、似ていますが、正確には違います。

「#if 1」であれば、「#if 1~#else」の間の処理が有効、「#else~#endif」が無効、
「#if 0」であれば、「#else~#endif」の間の処理が有効、「#if 0~#else」が無効
と排他になります。

Q割り込み処理について

割り込み処理について

初心者です。
割り込み処理について質問させて頂きます。

(1)割り込みルーチン中から別のルーチンに飛ばすことは可能でしょうか?
(2)割り込みルーチンの途中で最後まで処理を終えずに、割り込み先に復帰させることは可能でしょうか?

割り込み
{
   処理1
   a();   
       ・・・(1)
   処理2
   return;
       ・・・(2)
   処理3


以上、よろしくお願い致します。

Aベストアンサー

(1)別ルーチンに飛ばすというのがサブルーチンを呼び出すという意味なら一般的には可能です。
ただしANo.3で書かれているように、一般にサブルーチンは再入可能であることが求められます。なお、使用レジスタの保存は割込み処理ルーチンに求められるもので、サブルーチンを呼ぶからというものではないと思います。
あと、一般的に割込みスタックはそれほど深くないので可能な入れ子段数には注意が必要です。まあ組込みなら普通のプログラムでも注意は必要ですが。
別ルーチンに行ったまま帰ってこないということなら、処理系によるでしょう。割込み終了システムコールを使うなら別ルーチンで終了ということもできると思います。
(2)割込み処理ルーチンからの復帰はどこでも可能ですが、returnで戻れるかは処理系によります。
OSによっては最後はシステムコール呼び出しになっている場合があります。その場合はreturnでなくシステムコール呼び出しが必要でしょう。


人気Q&Aランキング

おすすめ情報