マイコンのROMに書いてある関数を呼び出すのに、次のような方法を使っています。
 1000番地のsub1と言う関数を呼ぶのにアセンブラで次のように書き、リンカで結合しています。
sub1: EQU 1000

 これをアセンブラを介せずC言語だけで行う方法は無いでしょうか。
イメージ的には次のような感じで1000番地のプログラムを呼びたいのです。
 この方法では上手く行かないのは分かっていますが、それを何とかしたいと思っています。

#define sub1 1000
sub1() ;

 宜しくお願いします。

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

A 回答 (8件)

定数を関数へのポインタにキャストすれば良い。



#define sub1 1000
main()
{
int i;
int i;
i = ((int (*)(int,int))sub1)(10,20); /*intの引数が2つあってintを返す関数*/
}
    • good
    • 0
この回答へのお礼

 やった! 有難う御座います。

 コンパイルすると、下記の結果になりました。

-------------------------------------------
#define sub1 0x1000
int i;
((void (*)(void ))sub1)( );
i = ((int (*)(int,int))sub1)(0x10,0x20);
-------------------------------------------
JSR @H'01000:24
MOV.W #H'0020:16,E0
MOV.W #H'0010:16,R0
JSR @H'01000:24
------------------------------------------

 更に次のようにすると、普通の関数と変わり無く使えるのが分かりました。

----------------------------------------------
#define sub2((void (*)(void ))0x2000)
sub2();
#define sub3((int (*)(int,int))0x3000)
i = sub3(0x30, 0x40);
---------------------------------------------
JSR @H'02000:24
MOV.W #H'0040:16,E0
MOV.W #H'0030:16,R0
JSR @H'03000:24
---------------------------------------------

 このような複雑な書き方はI/Oポートの構造体とか、C言語のクイズのような物で見るだけで、解説本には見かけないと思います。

 どうも有難う御座いました!

お礼日時:2009/05/18 23:39

蛇足ですが。



>更に次のようにすると、普通の関数と変わり無く使えるのが分かりました。
>#define sub2 ((void (*)(void ))0x2000)
>#define sub3 ((int (*)(int,int))0x3000)

ROMの内容は不変だと思いますので、ROMの関数のアドレスも不変だと思います。

なので、これらのROM関数の定義を以下のようにヘッダーファイル rom.h に書いて、いつもそれを使うと良いでしょう。

---rom.h---
#define InitSerialPort ((void (*)(void))0x1200)
#define ResetSerialPort ((void (*)(void))0x1258)
#define ReadSerialPort ((char (*)(void))0x12A2)
#define WriteSerialPort ((void (*)(char))0x12E4)
(以下略)
※関数名とアドレスは架空の物です。実在の関数名とアドレスとは一切関係ありません。

名前も、sub1とかsub2ではなく、上記のように「意味がある名前」にしましょう。

そうすれば、実際に使う場合、以下のように書くだけで良く、毎回#defineを書かずに済みます。

#include <rom.h>
void main(void)
{
  int r;
  char readbuf[10];
  InitSerialPort();
  ResetSerialPort();
  WriteSerialPort('R');
  WriteSerialPort('0');
  WriteSerialPort('1');
  WriteSerialPort('S');
  readbuf[0] = ReadSerialPort();
  readbuf[1] = ReadSerialPort();
  readbuf[2] = ReadSerialPort();
(以下略)
    • good
    • 0
この回答へのお礼

 分かりました。
 色々と有難う御座いました。

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

お礼日時:2009/05/20 04:42

>別にアセンブリしたりサブ・コマンドファイルの変更などが有り。


ここら辺は工程をバッチファイル化したり、ROM側のリンク時にシンボルファイルを書き出してJavascript/VBScriptなどで加工してアセンブラソースに加工するってのが定番です。


C言語だけでやると問題としては、
1.関数にパラメータがあるとキャストがめんどくさい。
2.リンカだけで解決するよりコードがわずかだが肥大化する。
3.関数ポインタの初期化を忘れてもエラーが出ない。リンクならエラーが出るからすぐ分かる。
    • good
    • 0
この回答へのお礼

 再度回答ありがとう御座います。

 今までの方法が、最良だったという事ですね。

お礼日時:2009/05/17 15:02

>#1さん



確かに関数ポインタを使えばよいですが、だからといって

>void(*sub1)(void) = 1000;

これはないでしょう。

# 本当に専門家?
    • good
    • 0
この回答へのお礼

 回答有難う御座います。

 名前はパラグアイの首都アスンシオンですか?

 20年前にアスンシオンの友人の家に数ヶ月滞在していたので、懐かしいなと思って。

お礼日時:2009/05/17 13:25

私もjactaさんと同じでリンカでの解決が良いと思います。


アセンブラによるのですが、
_sub1:: EQU 1000
とか外部シンボルになる定義を行ってください。
※ この場合::が外部シンボルの意味となる。そのほかexternと書くものや色々アセンブラによって違います。アンダーバーが必要かもC言語コンパイラの仕様によって変わります。

C言語側では、
extern void sub1(void);
と宣言して、
sub1();
と呼び出すだけです。
    • good
    • 0
この回答へのお礼

 早速の回答ありがとう御座います。

 秋月電商のH8キットでプログラムを作っているのですが、printf 関数は大きくてRAMに入りません。
 それでROMに書き込んで呼び出しています。

 現在zwiさんの回答と同じ方法でリンカで解決しているのですが、C言語の機能を引き出してC言語で解決できる道を探しています。

お礼日時:2009/05/17 13:09

C言語の枠を外れる話ですが、組み込み系のCコンパイラなら、そのコンパイラでどう記述するか機能が提供されていると思うので、コンパイラのマニュアルを見ましょう。


見つからなければ、だめもとで#1の方の書いた方法。
    • good
    • 0
この回答へのお礼

 早速の回答ありがとう御座います。

 秋月電商のH8キットの安いコンパイラを使っています。
 コンパイル時間が短いので気に入っています。

 シンプルな所が気に入っています。
 シンプルだから、基本的な事しか出来ません

お礼日時:2009/05/17 12:59

一番確実なのは、アセンブリ言語のソースで、関数名が外部結合のシンボルになるような擬似命令を記述することです。


関数へのポインタを使えばほとんどの場合動作しますが、規格上保証されているわけではありませんので。
    • good
    • 0
この回答へのお礼

 早速の回答有難う御座います。

 現在はアセンブリ言語の EQU を使って結合しているのですが、C言語だけで行う方法を探っています。

 アセンブリ言語が絡んでくると、別にアセンブリしたりサブ・コマンドファイルの変更などが有り、ミスが増えそうなのでC言語だけで処理出来ないかなと思っています。

お礼日時:2009/05/17 12:46

関数ポインタを使えば可能です。


void(*sub1)(void) = 1000;
sub1();

この回答への補足

 下記のお礼の補足です。

 使っているコンパイラが秋月電商のH8マイコン用です。
 機能が小さくて、C言語機能全体をカバーしていないかも知れません。

補足日時:2009/05/17 12:02
    • good
    • 0
この回答へのお礼

 早速の回答有難う御座います。
 このような回答を待っていました。

 しかし次のプログラムを書いてコンパイルしたのですが、
2129(E) ILLEGAL INITIALIZER TYPE
と言う、エラーメッセージが出てしまいます。

void test(void)
{
void(*sub1)(void) = 1000;
sub1();
}

 次のようにしても同じでした。

void(*sub1)(void) = 1000;
void test(void)
{
sub1();
}

 関数ポインタという機能を調べて、自分でも実験してみます。

お礼日時:2009/05/17 11:57

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

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

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

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

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

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

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

Aベストアンサー

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

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Q%P と %X の違い

アドレスを表示させるときの、%p は、%x と同じ16進数で表示される
んでしょうか?
表示の違いと言えば、大文字か小文字の違いだけなんでしょうか?
16進数の大大文字は「%X」というふうに、Xを大文字で指定すれば、
結果も大文字で表示されますよね。
%pはどういった意味なんでしょうか?



#include <stdio.h>
main()
{
char a;
short b;
printf("bのアドレスは%d,%p,%x\n", &b, &b, &b);
return 0;
}

Aベストアンサー

およそ #1 の通りで, アドレス値を出力するためには %p を使わなければなりません. %x は unsigned int を 16進で出力するという指定であり, アドレス値を出力するときに %x を使ってはいけません. 処理系によっては動いてしまうこともありますが正しいプログラムではありません.

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Q#defineの定数を文字列として読み込む

#define A "xxx"
#define B "yyy"
と定義しておいて

scanf("%s", str)
で読み込んだ文字列strが
"xxx"だった場合、"yyy"だった場合のように分岐したいのですが
このとき

if(str == "xxx")
のように中身を指定するのではなく

if(str == AA)
のように定数で分岐させることってできますか?

上記のままではできませんが、何か特別な関数とかでできるのでしょうか?

Aベストアンサー

こんにちは。

やりたいことの解釈ですが、(※勘違いの場合はすみません。)

1)マクロの名前(定義名)が文字列として格納された文字列 str があるとする。
 例)
   #define A "xxx"  //マクロ名=A
   char str[] = "A";   //"A"はマクロ名

2)上記の文字列 str を関数 func に渡す際に、マクロ名ではなくそのマクロで
  定義された文字列を渡したい。
 例)
   func( str );    //←この場合
    ↓
   func( "xxx" );  //←として展開される

ということで宜しいでしょうか?

だとした場合、少し回りくどいやり方かもしれませんが、以下のような文字列
変換用のマクロを定義してみては如何でしょうか?
※基本的には、他の回答者の方と同じように strcmp関数 を使用します。

■マクロ例
==============================
//文字列を定義したマクロ …※1
#define A "xxx"
#define B "yyy"

//引数を文字列として取得するマクロ
#define GETSTR(x) #x

//引数をマクロ名としてそのマクロで定義された文字列を取得するマクロ …※2
//注)<string.h>がインクルードされていることを前提とする
#define STR2MAC(str) \
!strcmp(str,GETSTR(A))? A : \
!strcmp(str,GETSTR(B))? B : str
==============================

上記マクロを使用して、関数 func にマクロ名が格納された文字列 str を
渡す場合は、
   func( STR2MAC( str ) );
のような記述になります。

前提として、※2のマクロ内でstrcmp関数を用いて文字列の照合を行って
いますので、<string.h>のインクルードが必要になります。

また、※1の文字列を定義するマクロの種類(パターン)を増やす場合、
※2のマクロの判定文もそれに合わせて増やす必要があります。

上記のマクロを使用したサンプルソースを下記に掲載致します。
注)エラー処理は行っていません。

■サンプルソース
==============================
#include <stdio.h>
#include <string.h>

//文字列を定義したマクロ
#define A "xxx"
#define B "yyy"

//引数を文字列として取得するマクロ
#define GETSTR(x) #x

//引数をマクロ名としてそのマクロで定義された文字列を取得するマクロ
//注)<string.h>がインクルードされていることを前提とする
#define STR2MAC(str) \
!strcmp(str,GETSTR(A))? A : \
!strcmp(str,GETSTR(B))? B : str

//プロトタイプ
void funcHoge( const char *str );

int main(void)
{
char sArg[128];

printf( "A or B ?>" );
scanf( "%s", sArg );

printf( "string1: %s\n", sArg );
funcHoge( STR2MAC(sArg) );

return 0;
}

void funcHoge( const char *str )
{
printf( "string2: %s\n", str );
}
==============================

■上記サンプルの実行結果
≫実行その1≪
A or B ?>A
string1: A
string2: xxx

≫実行その2≪
A or B ?>B
string1: B
string2: yyy

≫実行その3≪
A or B ?>hoge
string1: hoge
string2: hoge

以上です。

こんにちは。

やりたいことの解釈ですが、(※勘違いの場合はすみません。)

1)マクロの名前(定義名)が文字列として格納された文字列 str があるとする。
 例)
   #define A "xxx"  //マクロ名=A
   char str[] = "A";   //"A"はマクロ名

2)上記の文字列 str を関数 func に渡す際に、マクロ名ではなくそのマクロで
  定義された文字列を渡したい。
 例)
   func( str );    //←この場合
    ↓
   func( "xxx" );  //←として展開される

ということで宜しいでしょう...続きを読む

Q組み込みソフト。ROM領域にデータ

C でデータに const 属性をつけて、初期値を設定して定義すると、初期値は ROMにテーブルが作られますがデータ自体は RAM領域に配置されます。
RAMの節約のため、ROM領域にデータを配置する方法はないのでしょうか。

Aベストアンサー

#pragma section data = ".rodata"
//ROM配置したいデータ

#pragma section data = default

等のコンパイラやアセンブラのコマンドを使ってデータが配置される領域をROM領域に設定してください。
必要に応じてリンカディレクティブファイルまたはリンクディレクティブなどと呼ばれるファイルを編集してROM領域を示すセクションを追加してください。

注)他の回答にあるようにあなたの使用している環境に合わせてください。

Qセマフォとmutexの違いは?

排他制御としてセマフォとmutexがありますが、
この二つの違いがよくわかりません。
自分で調べてみたところ、
・セマフォ…プロセス間排他制御。複数ロックがかけられる。
・mutex…スレッド間排他制御。ロックは一つだけ。

と言うような違いがあるようなのですが、これだけの差なんでしょうか?
(これだけの差、と言ってる時点で筋違いだったら申し訳ありません)
また、セマフォをスレッド間排他制御に用いたり、
mutexをプロセス間排他制御に用いることは可能なのでしょうか?
可能だとしたら、これらが2種類存在する理由も教えていただきたいです。

Aベストアンサー

> >一般論としては、Mutexは「カウントを1に限定した」特殊化したSemaphoreです。
> とのことですが、これはWin32以外の環境だと
> これ以上の違いはないと言うことでしょうか?

「一般論」と書いた意味を取り落とされているのではないかと思います。

「一般論としては〇〇」なのですから、「Win32以外の環境」も含めて「各論」では「必ずしも〇〇とは限らない」とご理解ください。

なお、ご指摘のとおり、あるリソースを排他的に利用するだけであればMutexを使用するかわりにカウントが1のSemaphoreを使用することができます。(特定の環境での、MutexとSemaphoreの環境依存の動作を除けば、ですが。)

ではなぜ2種類が用意されている(用意されている環境が存在する)のかといえば、リソースの排他的利用は非常によくあることなので、これに特化した機能を用意すればより良いであろう、というシステムデザイナの判断によるものと考えられます。

ここで言う「より良い」は、あるデザイナにとっては「便利性」、また別のデザイナにとっては「消費リソースが少ない」と、これまた考え方はいろいろでしょう。

> >一般論としては、Mutexは「カウントを1に限定した」特殊化したSemaphoreです。
> とのことですが、これはWin32以外の環境だと
> これ以上の違いはないと言うことでしょうか?

「一般論」と書いた意味を取り落とされているのではないかと思います。

「一般論としては〇〇」なのですから、「Win32以外の環境」も含めて「各論」では「必ずしも〇〇とは限らない」とご理解ください。

なお、ご指摘のとおり、あるリソースを排他的に利用するだけであればMutexを使用するかわりにカウントが1のSemaphore...続きを読む

Q英語で「有無」の表現は?

よろしくお願いします。

英和辞書で引くと「有無」という言葉がありません。
有り、無しでの単独ではあるのですが、どうしても文章となってしまいます。
操作画面上での「有無」を英訳する場合の適切な表現を教えてください。

(例)
IC 有
IC 無
操作画面上のメッセージです。

Aベストアンサー

こんにちは。#2です。

補足を読むと ON と NO でいけそうですね。
on I/C   no I/C

「操作パネルに表示し・・・」ですが
I/Cが乗っていない場合、エラーが予測されるのであれば
I/C有り グリーン表示 
I/C無し 赤(黄)表示
とI/Cの文字を反転させビジュアルで訴えても良いような気がしますね。
仕様外になるなら無理ですが・・。

QH8Sで割り込み発生時の飛び先アドレスがRAM上にある場合の割り込み関数の記述方法

ルネサスのマイコンH8Sのプログラムを組んでおります。
プログラムの構成がBoot部分とアプリケーション部分に分かれており、
Bootはアドレス0番地から、アプリは3000番地以降の領域を使用するようになっています。
完成されたBootを使用してアプリケーションのプログラムを組まなければならなく、また、Bootは変更できないことになっています。
このBootの中のベクターテーブル上で、割り込みが発生した場合の飛び先のアドレスがRAM上になるように設定してあります。

このため、アプリケーションソフトでは、
割り込みが発生した場合のRAM上の飛び先に
FLASH ROM上の指定したアドレスにジャンプする命令を書き、
FLASH ROMのジャンプ先には、実行したい関数を書きたいのですが、

(1)RAM上の特定のアドレスからFLASH ROM上の指定したアドレスにジャンプさせる方法。
(2)FLAH ROM上の指定したアドレスに関数を記述する方法。
を知りたいのですが、
どなたか教えて頂けないでしょうか?
開発環境はHew4 言語はC言語を使用しております。
私自身が理解不足であるため質問内容が伝わりにくいかと思いますが、
宜しくお願い致します。

ルネサスのマイコンH8Sのプログラムを組んでおります。
プログラムの構成がBoot部分とアプリケーション部分に分かれており、
Bootはアドレス0番地から、アプリは3000番地以降の領域を使用するようになっています。
完成されたBootを使用してアプリケーションのプログラムを組まなければならなく、また、Bootは変更できないことになっています。
このBootの中のベクターテーブル上で、割り込みが発生した場合の飛び先のアドレスがRAM上になるように設定してあります。

このため、アプリケーションソフトでは...続きを読む

Aベストアンサー

特定のアドレスに特定のデータを書き込む方法。

例:6000番地から、順に、16進数の01,23,45,67を書き込む
unsigned char *addr;
addr = 0x6000;
addr[0] = 0x01;
addr[1] = 0x23;
addr[2] = 0x45;
addr[3] = 0x67;

もし「3014番地にジャンプするアセンブラコード」が「5A 00 14 30」であって、RAMの飛び先が6004番地なら
unsigned char *addr;
addr = 0x6004;
addr[0] = 0x5A;
addr[1] = 0x00;
addr[2] = 0x30;
addr[3] = 0x14;
と書けば良いです。

また「関数のアドレスにジャンプ」の場合は
unsigned char *addr;
addr = 0x6004;
int int_var;
void (*func_addr)(void);
func_addr = function_name; /*関数void function_name(void)のアドレスを受け取る*/
int_var = (int)func_addr); /*intにキャストする*/
addr[0] = 0x5A; /*JMP命令の1バイト目*/
addr[1] = 0x00; /*JMP命令の2バイト目*/
addr[2] = (int_var >> 8) & 0xff; /*アドレスの上位をセット*/
addr[3] = int_var & 0xff; /*アドレスの下位をセット*/

*注意*
上記の「0x5A 0x00」の命令コードは「たとえばの値」です。本当のJMP命令が何になるかは、アセンブラの命令コード表で調べて下さい。
また、上記では、16ビットアドレスを「上位、下位」の順にしていますが、H8Sでは順番が異なるかも知れません。命令コード表を良く見て「正しい順番」を確認して下さい。

特定のアドレスに特定のデータを書き込む方法。

例:6000番地から、順に、16進数の01,23,45,67を書き込む
unsigned char *addr;
addr = 0x6000;
addr[0] = 0x01;
addr[1] = 0x23;
addr[2] = 0x45;
addr[3] = 0x67;

もし「3014番地にジャンプするアセンブラコード」が「5A 00 14 30」であって、RAMの飛び先が6004番地なら
unsigned char *addr;
addr = 0x6004;
addr[0] = 0x5A;
addr[1] = 0x00;
addr[2] = 0x30;
addr[3] = 0x14;
と書けば良いです。

また「関数のアドレスにジャンプ」の場合...続きを読む

Qファイルopenエラーになってしまう。

はじめまして。
今、open関数を使用してファイルをオープン(3秒に1回)しているのですが、一定周期でエラーになってしまいます。
 周期:2時間7分

このファイルにIOをかけるのは、ここだけでcloseもちゃんとあります。openのリトライは3回(sleep(300))です。原因が全くわかりません。
どうか、宜しくお願いします。
(win2000 VC6.0)

Aベストアンサー

CreateFile() でもなく、fopen() でもなく open() を使っているのですね?

まずは、きちんとエラーの内容を調べましょう。

VC はしばらく使ってないので、良く覚えてないんですが open() はエラーになると
errno に詳細情報を残すはずです。マニュアルで使い方を確認して下さい。

まあ、少ない情報で原因を想定するとしたら

(1) close() しているつもりだが、実はできてない
(2) 他にバグがあり、open() に渡しているファイル名の領域を破壊している

というところでしょうか。

やはり、本命は (1) の方かな。7:3、いや、8:2位で。


人気Q&Aランキング

おすすめ情報