機械語なら俺に質問しろ!その2
■ このスレッドは過去ログ倉庫に格納されています
漏れは今までにC、C++、Pascal、HSP、JS、VBなど 数々の言語を極めてきたがやはり一番手にしっくりくる言語は機械語だ。 だから、機械語のことなら何でも質問しろ! ただプログラムのコードなんかは長くなるがな。 あ、ASMの話でもいいよ。 LSI C-80のランタイムかぁ。掛け算はアセンブラでがちに書いているだろうけど、 printf()系はCで書いたレベルだろうしなぁ。 この時代の組み込み用コンパイラのライブラリなんてサンプルプログラム感覚だろう。 ソースが付いてるのは好きに直せって意味だし。 このスレッドは天才チンパンジー「アイちゃん」が 言語訓練のために立てたものです。 アイと研究員とのやり取りに利用するスレッドなので、 関係者以外は書きこまないで下さい。 京都大学霊長類研究所 バイナリエディタで Hello, world! と表示するプログラムを作った頃が懐かしい 今なら nop や適当なパディング詰めておく事で アドレスを指定しやすくするなどの工夫が思いつくのだが >>5 fmtio.lというのがsprintfの実装でした。源流はunixですね。 素直なcで書かれてます。fmtio2.lというのがOS依存のprintf系実装。 1文字出力の関数だけが違って、フォーマッターの機能は共通に使えるように うまく階層分けされていました。 いきなりsprintfとか行っちゃうの? 例えばUNIXだったらwrite(2)を叩くぐらいから始めるのでは。 ところで機械語と言ったらアセンブリじゃなくていきなりバイナリ打ち込み? 実行ファイルのフォーマットの理解とかからスタートなん? >>17 いきなり打ち込みじゃないならアセンブラスレにでも行けばいい。 実行形式ファイルを丸々作る必要はなく、 char main[] = { ... とかでもいいだろうし、デバッガで実行中にメモリを書き換えてもいいだろう。 >>19 >char main[] = { ... >とかでもいいだろうし、デバッガで実行中にメモリを書き換えてもいいだろう。 RAM上のコードはプログラムとして実行できると決め付けてないか? 石の好き好きだろう データRAMはインストラクションフェッチ対象外、 と聞いたときは、カルチャーショックをうけたもんさ NULLが0じゃない系があるときいたときもね(関連) >>17 ,19 非組み込みであっても、平時はコンパイラ、アセンブラも活用するが、 デバッグ時や日常雑事でバイナリエディタでコード開いて、 ちょちょいっといじったりするのはマシン語のノウハウの領域 >>20 手段はいくつもあるという話をしただけで、決めつけている文章には見えないんだけど。 どう書けばよかったか教えてくれる? >>24 >手段はいくつもあるという話をしただけ >>19 に書かれてる手段というと ・char main[] = { ... ・デバッガで実行中にメモリを書き換え ↑の2つだけど、どっちもRAM上のコードを実行する話じゃないの? >>24 本人ではないが、「決めつける」というのは「どのような系でも可能であると想定する」 ということでは。 実際これが駄目だと思われるOSの例を思いつくけども。 特に断りもなくさらっと書くなら汎用な方法を書くべきではないかと。 >>25 > ↑の2つだけど、どっちもRAM上のコードを実行する話じゃないの? 一つ目の例は ROM になるかどうかは実行環境次第でしょ。 そして、RAM だとすると 19, 24 がどう悪いの? 19, 24 に書いてないことで非難されても困るんだけど。 >>26 > 特に断りもなくさらっと書くなら汎用な方法を書くべきではないかと。 俺はそうは思わないけど、君が汎用的な方法を書くことを非難したりはしないからどうぞどうぞ。 俺は、あれでもこれでもいい、という言い方をしたつもりであって、 あれかこれでなければならない という言い方をしたつもりはないんだよね。 沢山あるやり方の中から、毛色の違う二つを例示したつもりであって、網羅したつもりではない。 「網羅したつもりのように見える」という話であれば、 24 に書いたようにどう書けばよかったか教えてほしい。 「網羅すべきだ」というなら、すべきことをしなかったというのは認めるが、俺にはそんなつもりはないから、網羅したい誰かがやればいい。 >>27 >一つ目の例は ROM になるかどうかは実行環境次第でしょ。 const 付いてなきゃ RAM 以外ありえんのじゃないの? >>27 >俺は、あれでもこれでもいい、という言い方をしたつもりであって、 狭い知識でしか語ってないから馬鹿にされてんだよいい加減気付け 機械語っていうから低レベル(技術のレイヤーの)なことにすごく詳しい人が 書き込んでるのかと思ったらそうでもないのか。 単に「数字の羅列でプログラムが書ける俺ってカッケー」みたいな感じ? >>28 リンカスクリプトでもなんでも好きに書けばいいし、ROM に焼いてしまえば const つけなくても ROM だろう。 これも網羅したつもりはないからね。 >>29 俺は馬鹿にするなとは主張してないから、好きなだけ馬鹿にしたらいいし、君の広い知識も披露していくといいよ。 >>32 >リンカスクリプトでもなんでも好きに書けばいいし、ROM に焼いてしまえば const つけなくても ROM だろう。 char main[] なんてHEXファイルにも現れないもんどーやってROMに焼くの? 配列そのものと配列の初期値と勘違いしてないか? >>33 どっからどこまで焼くべきかなんて自分で分かるんだから好きに焼けばいい。 > 配列そのものと配列の初期値と勘違いしてないか? そんなん環境によると思うが、環境に合わせたコードを書けばいいだろう。 だいたい、俺はどこでも動くと言った覚えはないし、そもそも >20 に対して「決めつけてるつもりはない」という意味の 返信をしているんだから、スタートアップが _main にジャンプした場合にそこが必ず実行可能だと主張していない と解釈してもらって当然じゃないかと思ってるから、そうではないというなら説明してもらいたい。 そして、配列の初期値をコピーした _main を実行したとしても、コピーの必要のないグローバル変数の _main を実行 したとしても、どちらとも矛盾する主張をここまでにしたつもりはないよ。 で、 char main[] = { ... の場合に、配列の初期値なんてものを作って、実行時にコピーする環境が実在するの? 作れば作れるんだから実在するのかも知れないけど。 これ、俺はグローバル変数のつもりだったんだけど、もしかして、ローカル変数ならばって話をしてる?だとしたら 下らないことにつき合わせてごめんね。 マシン同士の会話が始まっちゃったんで どっちかが焼き切れるのを待とうや >>34 >で、 char main[] = { ... の場合に、配列の初期値なんてものを作って、実行時にコピーする環境が実在するの? ROM化前提ならそれが普通。 >>34 >で、 char main[] = { ... の場合に、配列の初期値なんてものを作って、実行時にコピーする環境が実在するの? ローダーがRAM上にプログラム読み込んで実行する環境しか知らんみたいね。 実家から戻ってきてみたら、まだやってたぜこれ そんなことよりおまえらことよろな LSIC-85 で、stpcpy見つけてうまくいったから、RX200で使おうとしたら、無かった。 LSIC.man 見たら、MS/DOSでしか使えないって書いてあった(w >>34 char main[]のアドレスが実行可能かどうかもアレだけど、 そもそもこれってリンクの段階でリンカはシンボル名しか見てなくてそれが関数 なのか配列なのかはお構いなしってことだよね。 普通Cの処理系ってそういうものなんだっけ? 例えば配列だとリンクできないような 処理系はないのかな? >>44 処理系に拠るんじゃないかな。 Cだと最初の初期化ルーチンで初期化を行った後にmain()を呼び出すけど、 リロケータブルオブジェクトには大抵セグメント情報が付いてて、コードセグメントに 配置された初期化ルーチンからデータセグメントのmain[]を呼び出せない アーキテクチャは普通にあるから、それをリンカがエラーとするか、データセグメントに 配置されたmain[]のアドレスを単なる値としてリンクを成功させるかは処理系に 拠る筈。安全の面では前者が望ましいのは勿論。 >>36 いや、俺の普通は ROM から直接実行する環境。 >>37 逆じゃないの? >>44 全ての処理系/実行環境で有効だと主張したつもりはないので、 説明不足だと言って非難するなら、そこは甘受しよう。 >>46 > >>37 > 逆じゃないの? > で、 char main[] = { ... の場合に、配列の初期値なんてものを作って、実行時にコピーする環境が実在するの? じゃあ君の普通の環境では、const 宣言もない main[] が ROM に配置されんの? >>45 手持ちのMac OS Xでやってみたら、リンクはできました。char main[]は データセグメントにある。 実行するとmainにジャンプした時点で死亡。実行属性が付いてないので。 mainが呼ばれる前に実行属性を付ける処理を呼ぶとmainを実行できたw >>46 自分は基本PCのOSしか知らないんですが、元の話で暗黙のうちに想定している 環境は何ですか? やはりプラットフォーム依存性が高いかと。 組み込み系とか興味はあります。 というわけで話を膨らませてみたつもりw クリックするだけで感染、みたいなのが多かった時期にソースを読んでると、 コード内にマシン語がデータとして居るのは、珍しくはない光景だったんだな 組み込みじゃないけど >>41 ごめん、LSIC-80の8085用オプションで。 >>49 いわゆるトランポリンコードを実行するにはスタックとかヒープに実行属性が 付いてないとできないけど、今はセキュリティ上の問題になる。 でも古いコードだとそういうテクニックを使ってたりするのがあるから、互換性を 保つには闇雲に実行属性を落とせなかったり。 ユーザーの皆さん、古いアプリのサポートを打ち切るのは単に新しいバージョン を買うように仕向けている訳じゃないんですよ、みたいなw >>50 > LSIC-80の8085用オプション 8085って8080から拡張された入出力と割り込み機能をサポートする命令が2つ増えただけで 公式には8080と大して命令変わってないと思ったけど、LSI C-80って8085用の特別な機能 でもあんの? アセンブリフェーズがNR80だから、正確には8080のコード吐くんですね。 SIMとRIMはニーモニックが認められないので、DC 20h/30h で書きます。 _LCC80ファイルの中身見直したら、-i8080 -RN で8085固有の指定はありませんでした。 非公開命令でも吐いたら面白いのになあ。仕事では使えんけど。 http://home.comcast.net/ ~kvaughn65D/UnDocum_8085_Instructions.pdf 私が自分用に作ったメモにもこのインストラクションは載ってました。 8080から改良するときに、ちょっと凝ったプログラミングをできるように という思想が感じられますね。 このページ、活字が小さくて見づらい。だれかtextにしてくれないかな。 うーんわからない。とあるUNIX(x86_64)のプログラムだけど、 (gdb) i r rax 0x00 rdi 0x800f5539034375816080 rip 0x800c7cff90x800c7cff9 (gdp) x/i 0x800c7cff9 0x800c7cff9 mov (%rdi),%rax (gdb) x/xg 0x800f55390 0x800f55390 0x0000000800f5bf98 (gdb) stepi (gdb) i r rax 0x800f5bfcc34375843788 rdi 0x800f5539034375816080 rip 0x800c7cffc0x800c7cffc なんでraxが0x800f5bf98にならずに0x800f5bfccになるの? テストプログラムで mov (%rdi),%rax を実行させても正しく間接参照する。C2Dのバグ疑ってもいいかな。 あっとタブが飛んだ 再投稿 うーんわからない。とあるUNIX(x86_64)のプログラムだけど、 (gdb) i r rax 0x00 rdi 0x800f55390 34375816080 rip 0x800c7cff9 0x800c7cff9 (gdp) x/i 0x800c7cff9 0x800c7cff9 mov (%rdi),%rax (gdb) x/xg 0x800f55390 0x800f55390 0x0000000800f5bf98 (gdb) stepi (gdb) i r rax 0x800f5bfcc 34375843788 rdi 0x800f55390 34375816080 rip 0x800c7cffc 0x800c7cffc なんでraxが0x800f5bf98にならずに0x800f5bfccになるの? テストプログラムで mov (%rdi),%rax を実行させても正しく間接参照する。C2Dのバグ疑ってもいいかな。 >>57 なんで最後に >(gdb) x/xg 0x800f55390 も一回やらんの? 変わってなかったのでコピペしませんでした。 (gdb) x/xg 0x800f55390 0x800f55390 0x0000000800f5bf98 それも疑ってみてました。正しいようです (gdb) x/3xb 0x800c7cff9 0x800c7cff9 0x48 0x8b 0x07 テストプログラム (gdb) x/4i aaa 0x4006f0 <aaa>: mov %rdi,-0x8(%rsp) 0x4006f5 <aaa+5>: mov -0x8(%rsp),%rdi 0x4006fa <aaa+10>: mov (%rdi),%rax 0x4006fd <aaa+13>: retq (gdb) x/3xb 0x4006fa 0x4006fa <aaa+10>: 0x48 0x8b 0x07 違うコンパイラでコンパイルしてみたらコンパイルが終了しない... >>61 >違うコンパイラでコンパイルしてみたらコンパイルが終了しない... C2Dのバグかも?w プログラムで合成されたCソースで、コンパイラへの負荷がかなり高い部分があって、 cc1がCPU利用率100%に張り付いて終了しない。 スラッシング起こすほどのメモリは使ってないようだけど。小一時間放置してみる 理解できない現象を何でも自分以外のせいにするのは素人。 コンパイルの山場は通過した模様。 たかだが50000行くらいのソースのコンパイルに20分くらいかかった。 >>61 >違うコンパイラでコンパイルしてみたら C2Dのバグ疑うかってのに、同じCPU違うコンパイラで偶々動いたとしてそれでいい訳? 行きつく先がC2Dかはわからないけど、動く条件と動かない条件絞っていかないと 原因にたどり着けないでしょ。 問題の個所は別の呼び出しでは問題なく通っているので、 原因がC2Dと仮定するとえれー複雑な条件が必須なはずでお手上げかもだけど。 実は「おめーがx64のアセンブラ知らねーのが原因、その命令は他のレジスタも 参照してる」とかいう罵声も期待してたけど、飛んでこないところをみるとそう じゃなかったらしい。 ちなみにシングルスレッドなので別スレッドが書き換えてるもないです。(多分) >>67 >ちなみにシングルスレッドなので別スレッドが書き換えてるもないです。(多分) プロセッサのバグ疑うんならOSも疑うべきだろ >>67 >行きつく先がC2Dかはわからないけど、動く条件と動かない条件絞っていかないと >原因にたどり着けないでしょ。 別のコンパイラ試すってのは条件絞ってることにはならんよ。 別のコンパイラを試した → 動いた → 前のコンパイラが原因 とはならない。可能性のひとつとして考えられるというだけ。 前のコンパイラが原因の可能性のひとつであるということは別のコンパイラを試す前と変わらない。 コンパイラ変えてコンパイルしなおすだけだったら、そうだろうね。 やってる本人が出来るといってる方法でやってるんだからいいじゃん。 やってる方法がトンチンカンだから書いてるプログラムがクソであることは容易に想像がつく 自分が想像できない事に言いがかり付けない方がいいよ。 ゴミクズみたいのが絡んできたし、これ以上有益な情報得られない だろうから退散します。 結果わかったら報告しに戻ってくるかも。 説明の責任は質問する側にあることが解ってないお子様なんだろう >自分が想像できない事に言いがかり付けない方がいいよ。 これが噂に聞くブーメランと言う奴か。 ゴミクズが粘着してるだろうなと思って覗いてみたら案の定粘着しててわろた。 説明責任とか言いながら、詳しく説明されてない方法を「それではできない」とか 断定しちゃう頭の悪さに気づかないのだろうか。 久しぶりに質問者側に回ってみたが、ゴミクズの最底辺さにはあきれ返る。 ほら、遊んでやるからかかってこいよ。 x64のいい逆汗ないかねえ IDAが有名だが、x64は割らないと無理だし。 汗・逆汗で食ってるわけじゃないからねえ 予算が下りないんだよ windbgじゃダメなのでしょうか? 他のデバッガにはそんなに便利な機能ありますか? 使途にもよるが、プラグインアリなら、かなり強力 VMと組み合わせて、仮想シリアルデバッグも楽しい あとntsd/cdbもよろしく。 今時, たくさん並ぶコンソールのスイッチを ON/OFF して, ロードスイッチを押す作業のなにが楽しいんですか? 俺なら, 迷わずアセンブリ言語を選択します 1バイトずつ打ち込むような体験も、一度はしてみとくべきだとおもうんだ 壊れやすいパチパチスイッチはこわいから、大幅に譲ってテンキー(0-9A-F)でいいよ ポリオミノを生成するプログラムを教えてください(できればC言語で) RX210 CPUマニュアルの内蔵ROMへのプログラム/イレーズの所を読んでいます。 FENTRYRのLSB側に01hまたは02hを書いた以降にROMリードが起きると ROMアクセス違反でコマンドロック状態が発生する。 だから 「RAMへジャンプしてから」 FENTRYR を書き替えている。 この理解で合っていますでしょうか? 上のはたぶん合っていると思うんですけど、そうすると、reset時にFCUに対して 周辺クロック通知コマンドを使うときに、hwsetup( )はROMで動くから困るんじゃ ないかなあ・・・FENTRYRのLSBに01hを書いてからコマンドを書くんだけど、 FENTRYRを書き替えた直後からROMアクセス違反が発生しちゃうことになる。 こんなところで仕事の質問をするものではない。 ばれたらどうなるか考えてみな。 答えられる奴が気軽に答えればいい 仕事の話なら、ここでヒントもらって、裏を自分で取ればいい そこは仕事。 今までwebの仕事ごくろうさん、午後から組み込みやってください、ソロで。 みたいな無理ゲーもいまどきあるらしいじゃないか。 俺はアマだが、汗しらない奴の、いまさら人に聞けない質問には付き合ってるぜ リングバッファのリード/ライトポインタから滞留数を計算する手法を教えてもらった のがこのスレだったような。 あれで滞留数の変数を追放できて役に立ちました。 今度のは新しい石だから、さすがにまだ体験者は居ないのかなあ・・・ マニュアルを何十辺も読んでると、こういう意味で書いてるのかなと判る所もあるけど、 ホント悪文だし。ここ2ヶ月でリビジョン3つも進んでるから変わってる最中。 RX210の、コード格納用ROMとデータ格納用ROMの章がようやく理解できてきた。 コード格納用ROMのプログラム手法の説明 40.6.4.2(5) プログラム方法 で言ってる手順 第3 サイクルのアクセスでは、プログラム対象領域の先頭アドレスに対して 書き込みデータをワードサイズで書いてください。この際、先頭アドレスは 128 バイト境界にアラインしたアドレスを使用してください。 と、40.6.2 FCU コマンド一覧 表40.6 FCUコマンドのフォーマット で言ってるWAの表現に矛盾があると思う。 WA: ROM 書き込み先アドレス 書き込みデータ2/8/128 バイトの先頭アドレス 前者は128byteアラインだけでいいと言っているし、後者は書き込みデータのアライン 2/8/128 に従え と言っている。 誰かこれ体験して解明した人居ませんか? 両方で128バイト境界って言ってるんだからそれに従えばいいじゃん へうのリンク制御文(ツールチェインのリンカタブ)とスタック(dbsct.c)の関係が判った。 スタックサイズ768がデフォで、これが変数領域のすぐ後ろに配置されてしまう。 「RAMの残りサイズ」がスタックになるような指定はできないのかな? >>100 フラッシュメモリって消去ブロック>書き込みブロックになってることが多いんじゃないの? あとはアドレスによってブロックサイズが異なってるとか。 >>104 この石では消去ブロックは全体で1個(実装分全部)です。1回の書込コマンド に続いてデータを2/8/128バイト書けるんですが、その時の書き始めのアドレス について、マニュアルの2箇所で矛盾した表現になっています。 マニュアルの元を書く技術屋さんは、自然言語で表現することが苦手な人が多いので 私は前者が間違いだろうと思っていますが、既に体験した人が居れば裏が取れると 思い、ここで聞いてみた次第です。お客さんを通じてルネには質問を投げて貰いましたが オフィシャルな回答が返ってくるのは当分先かと。 判ったらここに書きます。 だから、その2ちゃんで裏取るってのはやめれww 2ちゃんでヒント・経験談を取るのは大アリ その対称に、誰でも気軽に答えることができる。 んじゃ、また別の話で、ROMに焼いてあって起動するとRAMにロードして動くような コードの作り方ってのは? 古代のメインフレームだと、BALR 0,Reg using *.Reg でセルフリロケーティングな動作が書けたんだけど、H8系でへうだとusingの概念が 無いし。ROMからRAMにコピーしても再配置情報はROM空間のままだからRAMへ ジャンプしただけじゃ動かないよね。 何のための相対ジャンプ命令だと思ってるんだよ馬鹿か。 x86厨な俺としては、call $+(文字列長) ってのがすぐに思い浮かぶが 相対ジャンプの機構は理解しています。プログラムの要素はそれだけじゃありません。 ある関数だけをRAMにコピーしてそこをコールするとします。引数は3個まで (これは レジスタ渡しが保証されるから) その関数内のforループなどは相対ジャンプでできて いるから動くでしょうが、その関数がROMのどこかにある関数を呼んでいたらそのBSRの オフセットは元のROM位置からのオフセットであって、コピー先のRAM位置からの オフセットではありません。ROMからRAMへのコピーはできても、元のコードの再配置 情報は実行コードになった時点で失われてしまいますね。JSR 絶対番地 を使えば可能 ですが、このコールはBSR、このコールはJSR をプログラマが選べるCはありませんね。 こういうことを話してみて欲しいわけです。起動時ベクタは固定・行った先のROMも固定 そこからRAMにコピーして動くプログラムはどんな制約があるのか、どんな作りになれば いいのか・・・ アセンブリ出力を加工してからアセンブルすればいいじゃん。 ROMにある関数のリストがあるなら自動化できるんだし。 それも試みたことあります。JSRを手でBSRに直すとか。でも自動化できないし、 人的ミスを持ち込むことになるから、非・推奨な手法という評価になりました。 私が現在認識している制限は、単一関数で外部コールを含まないものなら可能。 複数の関数をリンクして作ったプログラムは、不確定要素が多くて不安、という段階。 Cコンパイラマニュアルのなかに、PIC/PID機能の利用 という章があり、ここで 一般的な注意事項が列挙されていました。usingの概念に似た手法が紹介されて いましたので、そこを読んでいるところです。PICは Positionn Independent Code、 PIDは Position Independent Data のことだそうです。 紛らわしい略語ですね。 >>110 > JSR 絶対番地 を使えば可能ですが、このコールはBSR、このコールはJSR をプログラマが > 選べるCはありませんね。 絶対番地呼び出したいなら、関数ポインタ経由で呼べばいいだけ。 それはROM関数だけを関数テーブルにするしかないんじゃないの。 関数名(実アドレス)でコールするからBSRかJSRか選べないという アホな話になるわけですよ。ROMを呼ぶとわかっている関数だけを コールテーブルにすれば終わりでしょ。 >>114 BIOSは処理ルーチンのアドレスに依存しないための工夫だから それを参考にすればいいってことだね では、割り込みはどう扱われるでしょうか? 今ターゲットにしている石は、 割り込みベクタテーブルの先頭番地をベクタベースレジスタに設定するタイプです。 LINKしたときの割り込みベクタテーブルはROMの中を指していますね。 これは関数ポインタのテーブルだから、割り込み処理は必ずROMコールとなります。 これと、ROMイレーズ/プログラム中はROMを読んではいけない、ということをどう 両立させればよいのか、その手法で悩んでいます。 >>100 の疑問、自分で考えた答は、後者が正しいと思います。 理由は、 第1、第2ステップでコマンドを書き込むアドレスが 「実装のどこでもよい」 と記述 されていること。それだと実際にデータを書き込むアドレスがどこかは、第3ステップの 書き始めのアドレスしか情報がありません。 終了コマンドも第1,2ステップと同じく 任意アドレスだし。 FCU側のプログラムを書くことを考えると、後者でないと整合性を 保てなくなります。 きっぱり言っておいてやるがな、 肩の力抜けwww ROM書き換え中は、割込テーブルレジスタもRAMに移しちゃうんじゃないん?と まずは思ったが、いまどきの石ってそこらへんややこしいんかな あるいは、そこを書きかえるときだけは割込とめるとか F3とかFBとか、「あのころ」はそんなことしてたな >>116 ROMリライト中に動く前提のプログラムってのがまず理解できない。 ROMを書き直す=プログラムを更新するってことだから、その時点で 割り込みベクタテーブルに処理が飛んでくる可能性はゼロではないの。 後だしでプチプチ情報出されても振り回されるだけだよ。 ROMリライト中に動いちゃまずい機能は ROMリライトの処理中は行わないようにすべきじゃ 風呂に入ってデバッグしてきた。なんとなく状況は理解できたと思う。 1)ROMの一部を書き換える組み込みアプリを作りたい 2)ROM書き換え中はROMへのリードアクセスは禁止 3)ゆえにコードをRAMにコピーしてRAM上で動作させたい 4)リンカーの出力するバイナリはROMからの相対アドレスである 5)RAMにコピーしたコードの関数アドレスを手作業でリロケーションはできない 6)さてどうしたものか まず2が真の時点でROM上でコードを動作させるのは不可能だから 全てのコードをRAMにコピーする前提で考える。 普通はロケーターを使うんだろうけど、話の雰囲気ではロケーターも 使えないっぽいからそれは考えない。 ならば全ての関数呼び出しを関数テーブル経由にするしかない。 第一段階としてブートストラップローダーを作る。こいつの仕事はROMの コードを全てRAMにコピーすることと、関数呼び出し用に全ての関数を 呼び出すためのコールテーブルを作ること。もちろんコールテーブルの 関数アドレスはRAM先頭のオフセットを加える。 割り込みベクタテーブルもブートストラップが作成する。 もちろんブートストラップ動作中は割り込み禁止。 次に、関数呼び出しを統括するスーパーバイザー関数を作る。この関数 はブートストラップがRAM上に作った関数テーブルを元に、引数で指定 された関数を呼び出す。こうすることで、関数名=アドレス値がコードに ビルトインされるのを防ぐ。 ここまで終わったら、ブートストラップがメイン処理に制御を移すだけ。 全ての処理は関数呼び出しに関数名は使わず、スーパーバイザー関数 に対して RAMが狭小で、フルイメージRAMに来れないんじゃないかとエスパー 機械語っていうか、石の話だが、関連雑談だな >>119 おつきあい下さりありがとうございます。10数年前、H8/16bitでそのような物を 作りました。その時はブートローダーの場所はイレーズしない・ROM書き換え/イレーズ する関数のみRAMに置く、という手法でした。ブートローダーは割込を一切使わず動く ように作りました。今回は、RAMはブートローダー全部を載せるぐらいたくさんあります。 ブートの目的は、ROMイレーズ・アプリをROMに焼くこと、焼かれたアプリはふつうに ROMで動作します。電源ONで動くのはブートなので、アプリがROMに入っているか チェックして、アプリに分岐するか、ROM焼きモードでブートの中で待つかします。 この方式だと、121後半の設定は不要ですね。ブート動作中は割込を使わないのは 今回も採用することになると思います。 >>123 そうなんです。ROM256/RAM32 とか、機種で多少はありますがそんな感じ。 ブートが固定ベクタを占有しちゃうんで、焼かれるアプリは固定ベクタを持たないこと。 ROM実装サイズがいろいろだが末尾に寄せて実装されている。FFFF0000〜FFFFFFFF とか、FFFC0000〜FFFFFFFF とか。なので、ブートからアプリにジャンプする際には 「固定の先頭番地」 という過去の手法が使えないので、固定の末尾付近(ベクタのすぐ前) を使うことになるのかな、と考えています。 後出し小出しが嫌われるのは承知していますが、課題全部はまだ承ってないし、 承っても1,2レスで列挙できるものでもないので、そこはご容赦くださいませ。 目下の選択は、ブートはROMで動く事にするか、ブートの主要部をRAMに転送するかで、 前者は実績があります。後者だと121の前半みたいなお膳立てをPGがやるわけですね。 う〜ん、厄介そうだなあ。 インテルの再配置ローダーみたいなツールがあればいいのに。 組み込みじゃなくてすまんが、ローダ付きのCOMファイルみたいのを連想するw > インテルの再配置ローダーみたいなツール 転送時点で再配置しとけばいいだけでしょ 読み込んでから再配置しようとか、難しく考えてるような EXEファイルと違ってROM上の実行コードには再配置情報は残っていません。 私が過去に実現したのは、再配置情報を含まないことが確認済みの関数だけを RAMに転送してコールするという手法でした。 hexファイルに再配置情報がないのだから 移動先のアドレスで動くhexファイルを作っておいたらってことだけど 移動先に移動させる仕掛けはどっかに必要だけどね ROM、RAM領域のアドレスが移動できるarmで boot時にROMは0から見えるけど 最終的には上位番地でROMの実行コードが走ることをやったことある (RAM領域は最終的に0番地から見える) reloc情報つきのモジュールを置いて、それを自前ローダにくわせてはだめなんか 超小型車輪の自社開発みたいになるが 感覚的には void* loader(void* _code, int _codesize, WORD* _relocs, int _relocssize); >>128 実行空間と格納空間を別に指定できるLINKの仕方がHewにあるかどうか なのですよ。ビルド−ツールチェイン−リンカのタブにそれっぽいのが無いみたい。 それがあれば、例えばFFFF0000番地にロードするイメージを00100000番地に格納 みたいなことができるのですけどね。ただ、コンパイラのマニュアルにpic,pidオプション ってのがある所から見ると、copyしても動くようなオプションつけてビルドしなさいと読める FFFF0000番地にロードするイメージのhexファイルを一度作って 00100000番地に格納出来るhexファイルに加工するほうが 悩まなくて済むような いや、だからそれは再配置情報が失われているって(w コンパイラマニュアルのリンケージエディタの使い方:セクションオプションの章を見ると >>130 みたいな割り付け方法は無さそう。なので一般的な手法としては pic,pid 指定を 付けてビルドし、130の例で言えば00100000番地でリンク、実行時にFFFF0000番地へ copyして実行、という流れになると思います。固定ベクタのResetVect(再末尾)は ROMの実行開始部を指し、そこは最低限RAMへcopyしてジャンプするコードを置く。 Hardwaresetup( ) の部分なんかはRAMで実行する必然性は無いので、reset時ROMで 実行してもかまわないでしょう。ただ、「RAMで実行することが必然」 な機能が何かという ことを考えてゆくと、以前の仕事みたいにROMとRAMを行き来する手法もありかな、と。 後者の利点は、CODEを置くためのRAMが少量で済むこと・再配置情報が無いルーチン だけを置くことで再配置問題を回避できること。 開始アドレスだけかえて複数のhexファイルつくって、 比較して、reloc情報を起こせばいいんじゃないかと そんなので済むかって? そんなので済むように書けるのが、機械語じゃないかw 以前書いたブートコードは、割り込みを使わずuartはポーリングで書いたのですが、 今回の石ではその手法は使えないことが判りました。なんと、uartのステータスregに RXRDY,TXRDYのフラグが無いの(*o*) だから受信・送信のトリガーは必ず割り込みで 取らないといけない。 これで解らないのがベクタとpic,pid機能との関連。 ベクタ(=割り込み処理コードのアドレス)、処理(=ROMの10000番地に実行コード) このベクタと処理をRAMの100000番地に書き写したとしても、ベクタの指す先はやはり 10000番地のままだから、割り込みが発生したら10000番地が実行されてしまうよね。 UARTをいつも見張ってると、CPUの手がそんだけ取られてるような ROMとRAMが同じアドレス空間にマップされるというマッピングが そもそもあり得ないんだけど。かりに意図してそうしているのなら 何らかのバンク切り替えメカニズムもあるはずだよね。 >>138 ああRAMは0が1個多いのか。 で、ROMのコードを実行する意図でないのならベクタの中身も 書き換えてRAMでrunさせるのは当然じゃないの。 >>100 の疑問の答が貰えました。やはり>>117 で正解でした。メーカーの人って 頑張るかと思ったけど、意外に素直にマニュアル間違ってますと認めちゃうんですね。 PICを吐くようコンパイラに指示してビルドしたけど、ベクタの中身は変わりませんでした。 原理的には想像はついてたんだけど、実際に出会ってみるとガッカリ。 ポジションインディペンデントであってセルフリロケーティングなわけじゃないもんね。 命令中の実アドレスは(再配置を要するものは)一切ダメ、ってルールブックに書いて おけばいいのに、そこの所をマニュアルではぼかして書いてあるの。 そんなもんコード上で書き換えないと変わるわけないじゃん。 そんな至れり尽くせりのコンパイラなんかどこにもないぞ。 これは実際に製品にするので、その辺をどうするか手探りしているところです。 石はRX210、内蔵ROM/RAM=128〜512/16〜64 ぐらい、cコンパイラの拡張機能で 専用の特殊regをいじる組込関数が提供されてます。set/get_btbl( ),set/get_psw( )等 RAMの実装番地は0番地からなので、copyしたら0番地に飛ばす、あるいは特定の低い 番地に飛ばすのは可能ですね。 古代のメインフレームでは BALR USING という手法でセルフリロケーティングなコードを 書きやすくしてくれたのですが、メモリが激安の現代にそんな手法がなぜ無いのだろう・・・ あ! ROMライタにはそういう機能があったなあ。コードは0番地で動くようにLINKして、 ROMに焼くときに元のコードのロードアドレスにFFFF0000を足して転送、という機能。 (昔のライタなので8桁はムリだったかも) ルネ提供のライタにそういう機能があるかな。 ちょっとどうかなと思う発想もあるが、正直よその石のことは想像でしか聞けないし、 雑談ネタを投下してくれてると思って流し読みすればおk 打診が来てから3ヶ月、未だに仕様のカケラも来ません。仕方なく石のマニュアルから お試しコードと、過去の情報からアプリの下書きを書いてます。こういうのがあると 仕様が来だしたときちょっとした手直しで目的のコードにできるから。 ソフト会社だと仕様が来てから動くしかないから、こんな時点では動けないし、 仕様が来たときには納期が破綻してるというケースばかりでした。 >>137 通信以外には何も無い、内蔵ROMライターみたいなアプリでした。 ROMに書いてレディを待つ貼りつきの間、割り込みが使えないのでそこでポーリング。 それってまだお金もらってないってことだよね。 そんなんで先行投資しちゃっていいの? こっちが心配することじゃないけどさ。 お金はいずれ貰えます。ハード屋さんは私に発注することを上司に承認取った上で 少し高い石を選びました。 ハードが一段落したらソフト要求仕様を書き上げそこで 一般のソフト会社に投げるネタになります。そこから見積もり依頼→見積もり→承認。 出来レースにしないために相見積もりしてもらうのもかまいません。partの合間なので フルタイムなら1人月分ぐらいの先行かな。生活のためではなく面白いからやってるだけ で、自分が今のソフト屋と比べて仕事がのろいのは自覚してるから、本決まりになって から間に合うように、先回りできる分野は先に片づけるようにしてます。 本格start以降の期間には、ダンピングの非難が出ない程度のお金は貰います。 >>130-135 辺りの問題は、石の設計思想にその解決手法が用意されているようです。 内蔵ROMの空間が2とおり用意されていて、小さい方の空間で実行している時もう一方 の大きい空間のイレーズや書き込みを実行すればアクセス違反が出ないとの事らしい。 マニュアルの自然言語の表現で、ある文脈のROMがどちらを指すのかあいまいなので そこを再確認待ちです。 私はRAM空間用にLINKしたコードを小さい空間に焼いて、 起動時RAMにコピーしてそこへ分岐、という手法を試していましたが、これでラッキー。 >>148 の再確認はOK貰えました。 以前はROMがbyte書込だったので問題ない事が 今回はword書込で問題になることが見つかりました。 S30AFF7FC080EF773B1D0E6B 最後C084 に ライト、 S315FF7FC0885645523F00000000A4C57FFF522000009F C088からライト S314FF7FD26023F3601158117125FF405102660102BA D260〜D26Eにライト、 S315FF7FD26F7F957F957F957F957F957F967F957F958A D26Fからライト 1行目の末尾 C084の0Eは、0EFFにして書き込まなければならない。 3行目の末尾 D26Eの02は、02FFを書いてはならない。その次の行の D26Fの7Fが来た時点で初めてD26Eに027Fを書いてよい。 どのように実装しようか考え中です。 なんつーんだっけ? Sファイル? そいつを運用で奇数バイトから始まるものは受け付けないってできないの? そういう折衝する可能性も考えずに言われたままにほいほい実装するの? つーか、そもそもそ半端なワード(2バイト領域)はROMから読み出してから 書き戻せばいいんじゃないの? クリア済みが保障されているならクリア値で 埋めればいいんじゃないの? 土方は何も考えない分気楽でいいなぁ。 そう。モトローラのSフォーマットファイル。ふつうのリンカが出力したファイルですよ。 それを運用で焼いてあげませんって処理系に言われたらヤでしょ。 クリア値で埋めるのも、パソコンなら1MB用意してもいいでしょうが、 ROM16KB/RAM16KB ぐらいの空間で動くように実装するんです。 したがって流れの中で解決する必要があります。イレーズは全部いっぺん、 ライトはアドレス・データであちこちに書けますが、2度書きはできない (しない) のが 原則ですね。 ROMの性質上、xxFFのワードにxxyyを上書きするのは可能だろうと 思いますが、マニュアルで保証されてはいません。 半端なバイトを取っておくようなアルゴリズムを書いてみたのですが、いまいちすっきり しません。ROMから読み出すアルゴリズムのほうがスマートなのは確かなので、 xxFF→xxyy FFvv→xxyy の重ね焼きが可能か、メーカーに質問投げてみますね。 >>103 へうでのリンカスクリプトの使い方がやっと判って、スタックの割り付けも臨む 場所にできました。ビルド−ツールチェイン−最適化リンカタブの中の、セクション カテゴリーを開くと、アドレスとセクション名の対応が表になっていて、それを編集 するのですね。-start=B_1,R_1,B_2,R_2,B,R/06000,SI/07D00,PResetPRG/0FF7FC000, C_1,C_2,C,C$*,D_1,D_2,D,P,PIntPRG,W*,L/0FF7FC080,FIXEDVECT/0FFFFFFD0 自分でこういう制御文をコマンドラインに書くのに慣れていたので、どこにそういうの書く のだろう??と。 へう推奨のセクション割り付けパターンが、アライメント1,2,4の順なのですね。 これがまた違和感。従来はアライメント4,2,1でした。勿論自分でそういう指定に 直すことはできるのですが、この推奨パターンにはどんな意味があるのでしょう? あと、コード部配置順も、resetprgが先頭、以下定数、実行コード、割り込みコード、 ラベル、文字リテラル という推奨順なのですが、何で定数の間にコードを挟むのか 理解しずらいんですよ。 ×臨む ○望む ×理解しずらい △理解しづらい ○理解しにくい 校正どうもです。 のぞむなんてどこで書いたか忘れて探してしまった(w 打診のときは移植みたいな話だったのに、機器がみなネットワーク対応になってるから ネットワークプロトコル実装しなくちゃいけないっぽい・・・アプリ本体よりそっちのが余程 でかいじゃん。 >>135 で、ポーリングは使えないと書いたんですが、RXRDYのステータスをポーリング あうるのではなく、受信割り込みがあったことをポーリングすればその手法自体は書ける ことに気が付きました。 「入力が入り次第すぐそれを使う」 という点で一貫してるので、 単純なプログラムを書くには適した手法でした。わざわざその手法で書き直す必然性は ないので後戻りはしませんけど。 RXシリーズは、石の設計思想にコンパイラやOSの存在が組み込まれていますね。 SIとSU(割り込みスタックとユーザースタック)が別 とか、特権命令があって、PSWの スーパーバーザーモードとユーザーモードを区別するbitにより例外を発生させるとか。 でもMAX50MHzでWinみたいなマルチタスクを実現するわけでもないし、OS無しで 単純ループで書いてるだけだとこの設計思想のありがたみは感じないなあ・・・ 電源でなぜいつも苦労するのかは、どなたか判りますか? LAN通信機能は不要だそうです。serialのみ。 これならなんとかなるかな。 飛び込みで8085の仕事が来た・・・CPU以外にも 8251 8253 8255 どうやって石調達 してるんだろ? 結局ここで推敲してもらったstpcpy( )は使わなくなってしまいました。 >8251 8253 8255 どうやって石調達してるんだろ? 量産でなければ普通に手に入る。秋葉原の店頭でもまだ見掛けるし。 汎用チップの需要って案外ワンオフとかであったりするんで ロット納品とかでなければ普通に売ってるよ。 チップバラで買ってハンダ付け名人のおばちゃんが組み立てるのか〜・・・ 手作りはお互い様ですね。今朝HEXを送信しました。 256のROMまだあるのかな? その後4回手直ししてHEXを送付しました。全部パツイチで動きました。 ふつうのソフト会社なら30分の仕事にする所、暇なので16hもかけてしまって\3マソ(w 明日から本業のRXに戻れるかな uartに割り込み来ない・・・と思ったら、PMR,PDRより前に マルチファンクションピンコントローラのレジスタ設定が必要だったorz しかもこっちの章が後なのに設定は先とか・・・もうね、意地悪! まだ割り込み来ない・・・やったこと:hwsetupで、マルチファンクションピンコントローラの P20〜P33PFSでTXD/RXD端子に設定、PORT3.PMRとPORT2.PMRでTXD/RXD使用、 ICU.IPR[218]と[226]=優先度2、IER[27]と[28]=0Fと3C(SCI1,6のERI,RXI,TXI,TEI許可) リセット直後でINTBに可変ベクタテーブルの先頭設定、hwsetup( )から戻った所で set_psw( )でPSWのIbitをオン。SCI1と6のSMR,BRR設定してSCRに50h(REとRIE)書いた。 これでシリアルにデータ入れても割り込み来ない。uartのレジスタの辺りダンプすると みんな00になってる。BRRやSCRやRDRは非ゼロが見えるはずなのに・・・ 何かまだ設定忘れてる?? と、思ったら、モジュールストップレジスタというのがあって、ユニット毎に動作を開始 しなきゃいけないようになてましたね〜 >>167 さん、基本中の基本をご存じなら >>166 あたりで指摘してほしかったですね〜 結果はもうじき来ます。 基本中の基本って言われたら 基本を調べるよなふつう つーか、私だって全てのCPUのレジスタ構成を把握しているわけじゃないもん。 自分が使うCPUならレジスタ構成を把握するのが基本だろって話だよ。 自分が使うユニットの章しか読まないでコードしてもなんとか動いたんですよ、H8Sとか。 概要の章に、何章までは全部読んで理解しないと使えないよ的な前置きが欲しかったな。 1600ページもあるの、全部なんか読んでられないわ。 モジュールストップ解除したら動きました。やれやれ・・・ タイマ割り込みが来ないのもこれのせいでした。この石は省電力が売りなので、 使わないユニットにはクロックを送らないことで省電力を実現してるんでしょうね。 これでやっと本来のアプリのデバックに入れます。 評価セット借りてきて、自分のパソコンにつなぎました。 ドライバのインスコで神経すり減らしたけど、動いたら快適。 DATAflashの書き込みと読み出しがうまく行きました\(^o^)/ 同じ手法で内蔵fROMの書き込みもしてるので、この先Sレコードの書き込みも うまく行きそうです。デバック用にWDTリフレッシュ殺して動かしてますが、 うまく通信できてます。 で、忘れた頃にWDT入れたら、真っ青になるとw # 茶化してるだけねw FFFFFFFC番地に入っているアドレスに飛ばすc文はどう書けばいいですか? ( (void*)(0xFFFFFFFC) )( ); ってやると、FFFFFFFC番地に飛ぶ命令が出ちゃう。 >>177 ポインタサイズが32bitと仮定すると unsigned long pl; void (*func)(void); pl = *((unsigned long *)(0xFFFFFFFC)); func = (void *)pl; 普通にこうすりゃいいだろ ((void (*)(void))0xFFFFFFFC)(); 分かり辛いなら void (*func)(void) = (void (*)(void))0xFFFFFFFC; func(); (*((void(*)(void))(*(unsigned long *)0xFFFFFFFC)))(); こうかな…?手元に環境が無いのでちょっと自信ない >>180 斜め読みしてたすまん こうだな (*(void (**)(void))0xFFFFFFFC)() 機械語スレでCごとき高級言語とか # デスクトップでも__asm は試作で重宝してる asmすらこのスレにはふさわしくないんだよなあ emitしないと >>182 さんので通りました。 ありがとうございます。 MOV.L #0FFFFFFFCH,R4 MOV.L [R4],R5 JMP R5 このcはasmの行を挟み込む機能は無くて、asmのインライン関数を吐かせるんです。 判らなかったら、#pragma inline_asm func void func(void) { } の中に上の3行を挟んで書こうと思っていました。 「ポインタのポインタ」 で理解するより3行のasmのほうが私には理解し易いですね。 分かり辛いなら typedef void (*funcptr_t)(void); funcptr_t* p_func = (funcptr_t*)0xFFFFFFFC; (*p_func)(); とか >>185 ポインタのポインタが解りにくいというより C言語の関数ポインタの書式が分かりにくくしてる原因だと思う そうですね。asmでの理解ならすんなりいくのに。 ユーザーブート領域のプログラムをデバックしようと思って、その空間でLINKした コードをダウンロードして、リセットベクタをそこを指すようにして実行してみると、 対象領域がみんなFFになってる。未実装として読まれてるみたいです。 端子2つと特定番地の内容でブートモードになる、とマニュアルに書かれていたけど、 なるほどこういうことだったのか。リセットベクタを含む固定ベクタはアプリにだけLINK するものですね。起動時にそういう端子入力ができるようにハードを直してもらいます。 機械語オーライなら、もちろん、call convention は気にするよな? 組み込みのCの処理系がどうとなってるか詳しくないが、 typedef int (__cdecl* myfuncptr_t)(int, int); とかって書くようにしてるぞ。 __cdecl がデフォルトだったと思うので __stdcall しか書かないな SCIの受信とDMACを連携して動作させられるじゃないですか。あれってバイト数は DMACに設定するんだから、何バイト来るか判っている場合にしか使えませんよね? DMACは基本的に固定長のデータ転送に使うものだから 不定長のデータには使えない。 watms(int ms) 関数が素通りしてるっぽい・・・ RX210 void waitms(int ms) { hwsetup( ) で MSTP_CMT1 = 0; はやってる。 // 入力:ミリ秒単位の数値(50mSまで)。誤差の少ないwait関数。 CMT3.CMCOR = PCLK/128/1000*ms; // 1KHz(1mS)の分周値*mS CMT3.CMCR.WORD = 0x00C2; // Φ/128 セレクト,CMIE3許可 CMT.CMSTR1.BIT.STR3 = 1; // カウントUP start // do { } while( CMT3.CMCNT ); // 一致を待つ // ↑CPUマニュアル 25.2.4には、一致するとCMCNTは0になると書かれているが // 0である128clkの間、別の割込で他の箇所を実行しているかもしれない。 // そこで下記の割り込みを待つようにする。 do { } while( CMT3.CMCR.WORD & 0x40 ); // 割り込みを待つ } #pragma interrupt(Excep_CMTU1_CMT3(vect=VECT_CMT3_CMI3)) void Excep_CMTU1_CMT3(void) { // 1mSタイマ割込み処理 13.02.28 CMT3.CMCR.WORD = 0x0082; // Φ/32 セレクト,CMIE3禁止 CMT.CMSTR1.BIT.STR3 = 0; // カウントUP stop } これで1msのn倍waitできると思ったんだけど、すぐリターンしてくるみたいなの volatile? 機械語じゃなくね?w 保守してくれてるとおもって気にしてないが 素通りしてるとか言う前に吐かれたマシンコードを見るのが 先じゃないのかな。 ああ、「マシンコード」か。見慣れない字面だから空目してびっくりしたわ。 マシンコードは見たんですよ〜 すぐ気が付くようなミスは無かったと思う。 CMT3.CMCOR = PCLK/128/1000*ms; // 1KHz(1mS)の分周値*mS MOV.L #00088000H,R4 MUL #90H,R1 MOV.W R1,1CH[R4] CMT3.CMCR.WORD = 0x00C2; // Φ/128 セレクト,CMIE3許可 MOV.W #00C2H,18H[R4] CMT.CMSTR1.BIT.STR3 = 1; // カウントUP start MOVU.W 0H[R4],R5 BSET 01H,R5 MOV.W R5,10H[R4] do { } while( CMT3.CMCR.WORD & 0x40 ); // 割り込みを待つ L26: MOVU.W 18H[R4],R5 BTST #06H,R5 BNE L26 RTS void Excep_CMTU1_CMT3(void) { // 1mSタイマ割込み処理 PUSHM R4-R5 CMT3.CMCR.WORD = 0x0082; // Φ/32 セレクト,CMIE3禁止 MOV.L #00088000H,R4 MOV.W #0082H,18H[R4] CMT.CMSTR1.BIT.STR3 = 0; // カウントUP stop MOVU.W 10H[R4],R5 BCLR #01H,R5 MOV.W R5,10H[R4] POPM R4-R5 RTE do whileの脱出条件が間違っているようにしか見えない。 そもそもなぜdoなのか。通常のwhileではできない理由があるのか。 そこらへんが理解できないな。 あとコンパイラによってはdo { }が空文だと最適化でコードにしない ものがあったりするので(昔のMS-Cとかね)最適化オプションは 全てオフにしてから確認するといいかもね。 >>198 で、18h[R4]にC2hを入れてから、L26:の所でそこのbit6が1の間ループ。 >>199 の割り込み処理で 18h[R4]を 82h にしてます。 あ、書いてる途中でレスが・・・ while { } だと前判定、do { } whileだと後判定になるから。 今のケースの場合は一緒ですけどね。前判定だとBZ で脱出、その後ろに B 続行 ってなるのがイヤだから、ってのもあります。 見つけた〜!とおもう。hwsetup( )で MSTP_CMT1 = 0; // CMT unit1のクロックON とコメントに書いてあるけど、これがウソで MSTP_CMT2 に0を書くべきでした。 SCIで体験した事だと、ユニットにクロックを与えないとレジスタにイネーブルを 書けなかったから、コンペアマッチタイマもそうだとおもう。 今基板帰してるから、また借りたら確認しますね。 基板につける原クロックって水晶ですよね。CPU内蔵のクロック発振器ってどんな 原理なんでしょう? RC 発振器 でぐぐったらwikiが先頭に来たけど、余計解らない語句ばかり出てきた(w 何となくだけど、どの原理もLSI内部に納めるほど微小化できるのかな?とは思った。 基板は、ユーザーブート領域に焼く方法の所で引っかかってるみたいです。 >>204 CPU内蔵ならクリスタルじゃなくてPLLじゃないの。 たぶんクリスタルよりPLLのほうが正確だし。 あ、なんかPLLも基準周波数にクリスタルがいるらしい。 勘違いだったかも。 CPU内蔵のPLLは、基準周波数を分周または逓倍するために使いますね。 204の話は、CPUみたいなLSIの内部に焼き付けられる原クロック回路は、 クリスタルみたいなデカいものじゃなさそうに思えるけど、どんなものなのかなあ・・・ ユーザーブート領域のコードが動いたらしいです。私が確認に行けるのは木曜ですが x86-64の64ビットモードで動かない32ビットx86の命令ってどんなものがありますか? DAAとかなくなったんでなかったっけ? あとLAHFとか。 ユーザーブート領域のコードが動いたのは誤報でした。FF7FC000〜の空間には コードが焼けない/読めない状態のままです。困ったなあ・・・ RX210 規制の間に本番用の基板でデバックが進みました。 デバック用の基板ではユーザ空間しか焼けませんでした。 ユーザーブート領域に焼いても、そこで実行したコードでROMアクセス違反は 発生します。ROMを焼くコードだけRAMにコピーしてそこを呼ぶ手法を採りました。 欲しい機能の実装はだいたい確認。引き合い時2人月だったお金も、3.5人月 もらえました。36度の書斎でのデバックは2,3日で済みました。やれやれ・・・ 汗が基盤に垂れなかったのだろうか いや、液状のほうの汗なw 書斎が32度以上のときは、アイスノンを頭に巻いて 30分ごとにリビングに避難しながらやってました。メインは未明の頃。 8085ではメモリマップトI/O(ex:F000番地が8251のTXD/RXD)しか やったことがないのですが、8085にもIN/OUT命令はありますよね。 オペランドは8bitのアドレス。 このIN/OUT命令を使うときはハードをどのように組むのですか? もうちょっとくやしくお願い。名前からすると「メモリじゃないよ」という信号みたい ですね。 IN 04h と書くと、メモリではない04番地からリードですね。 そのとき8251を04番地に配線?すると上と同じ機能が得られるのですか? 私が出会ったのは217のようなシステムばかりでしたが、それは偶々? 8251側ではRD/WR信号とアドレスのLSBでI/Oレジスタを区別していましたが IN/OUTを使おうと思うとその辺はどうなるのでしょう? LDA/STAは3バイトだけど、IN/OUTは2バイトだからこっちのほうが小さいけど そういう理由ではハードは決めないのですか? >>219 あんたの知っているシステムでは、8251自体はアドレスバス上位4ビットがONで下位ビットOFFのときに チップセレクトされるようにつながっているのだろう。 8251のチップセレクトをするに当たって、メモリ空間を使いたくない場合は、IO/Mをデコードして OFF(M)のときにチップセレクトされるようにすればいい。 私の知っているシステムでは、メモリ空間を広く取るためなどの理由でそうしていた。 命令長が理由でどっちを選択するか検討するという話は余り聞かないな。 壊れた動画ファイルをバイナリエディタで開いて、そこから一コマでも画像ファイルにして抽出することってできますか? 拡張子は3gpで昔携帯で撮ったものです 少し調べてみてmdatって文字列は確認できたんですが、ヘッダ周辺はだいぶ壊れて上書きされているみたいです バイナリ全くわからないんだけど、規則的に色の情報が配置されてるって単純な構造でもないのかしら… >>220 なるほど。聞いてみてよかったです。ハードの設計者の意向でそのような 切り分けがなされるのでしょうね。私の知っているシステムではアドレス上位4bit でチップセレクトされる先を決めるICが入っていました。220のやりかたのほうが 使う石が少なくできるような気がするのですが、私の顧客の伝統なのか拡張性? のためなのか、私の付き合った現場ではメモリマップトI/Oばかりでした。 8085+8259のシステムで、IRRレジスタを読む必要があります。 コマンドレジスタのアドレス0側を読むとIRRまたはISRが読め、その選択は リードに先立つOCW3でコマンドレジスタのアドレス0側に書きます。 似たコマンドでOCW2というのもあり、これもアドレス0側に書くのですが、 OCW2とOCW3の違いは、書き込み内容のbit4,bit3が01か00かで区別される と理解してよいでしょうか? SAUTO: ; store 16-bit automatic variable ; VAR = HL XTHL MOV E,M INX H MOV D,M INX H XTHL SAUTOX: あれ?なんで2行改行になるんだろ? XCHG DAD SP MOV M,E INX H MOV M,D XCHG RET スタックにHLをストアするルーチンらしいのですが、前半が何をやってるのか よくわかりません。SAUTO2:: の入口は LXI D,4 してSAUTOXへジャンプする ので判り易いのですが・・・ 8080のASMです。 >>226 スタックトップに積まれたアドレスからEとDに2バイト読み込んだ後、スタックトップに積まれたアドレスを+2更新してる スタックトップというのはSPが指している場所ですよね。そこにあるのはアドレス ですか?+2更新されるのはSPではありませんか? SAUTOXに来た時、他の SAUTO02/04/06・・・からはDE=4/6/8・・・なのに>>225 から来たときはDEには (SP)の内容が入ってますよね。226でやってることはストアすべきアドレスをHL に計算して、入ってきたときのHLの内容をストアするのですが、225からくると DEにあるデータはオフセットではなく不定のメモリ内容な気がして、そこが不安 なんですよ。 その前後で、スタックをどう使ってるかだよ、意味論的に SAUTO HLに16bitの値を格納し CALL SAUTO DW オフセット値 の形式で呼び出すとスタック上に確保されたローカル変数の領域(SP+オフセット値)にHLの値を格納する SAUTOからの復帰はオフセット値を格納した次のアドレスから継続する SAUTOX DEにオフセット値 HLに16bitの値 を入れてCALLするとスタック上に確保されたローカル変数の領域(SP+オフセット値)にHLの値を格納する あ、いろいろレスが・・・ありがとです。そうか、CALLの後ろに DW オフセット この呼び出し形式が解らなかったんです。pushされたリターンアドレスを 使わないと DW オフセットを取り出せないから225みたいなコードになってる んですね。やっと解りました。 >>233 はい、わかります。 >>224 よいです。 8085のデータブック読むと、機械語の説明のところにクロック数とステート数という 欄があります。クロック数はΦクロック(またはその半分)が単位でしょう。 ステート数というのが、クロック数のだいたい1/3ぐらいの数値なのですが、 これが何のことか、ブック中では説明なしに使われています。 このステート数というのはどういうものなのでしょう? >>236 http://www.inf.pucrs.br/ ~calazans/undergrad/orgcomp_EC/mat_microproc/intel-8085_datasheet.pdf どうもです。私が読んだのは沖電気の日本語版で、そのソースがインテルのこれ なのでしょうね。全部読み下すほど英語力無いのですが、Table 3 Table 4 を 参照して各命令ごとに合計をとったものが日本語の資料に追記されたと 思えばいいでしょうか? M1,M2,M3がステート数に相当するものですね? >>768 生まれた頃は暖かい家庭だったんじゃね、今からは想像できないだろうけど 検索してもx86命令とx64命令しか見つからないんですけどリアルモードってx86命令でいいんですか? リアルモードはほぼ16bit推奨環境 プリフィックス付かどうかで動作変わる命令は操作対象が16bitであると解釈される 例) INC AX → 40、INC EAX → 66 40 付く分動作が遅くなる、つまり、リアルモードで32bit操作は期待するほど速度でない プロテクトモードは32bit環境 例)INC AX → 66 40、INC EAX → 40 操作対象が16bit幅な命令も使えるけどリアルモードより遅い x64もレガシーモードで動作させればリアルモードを使えるけど、使える命令はx86命令に限定される、ハズ なのでいいんですか?と聞かれたら概ねいいですと答えていいんじゃないですかね >>242 ありがとうございます。 起動時のCPUはリアルモードで動作するという事で、 OSのブートプログラム書くのにリアルモードでのオペコードが必要なのに、 リアルモード用のオペコード一覧が見当たらないなと悩んでました。 機械学習に関してもここでいいでしょうか? 現在、Cで深層学習のお勉強プログラムを書いています。 Caffeなどそのもののライブラリを使わずに実装したいと思っているのですが、 自動微分がどうしても必要になりますが、これを高速にすることが可能なライブラリはありませんか? Hyper-v環境でルートパーティションにおけるcpuid命令は、通常の10倍遅い VTなら、cpuidは無条件でVM Exitするって書いてあるぞ。 遅いのは仕方ないね THIS IS AN ACCUMULATOR. THIS IS A REGISTER. AHH ACCUMULATOR REGISTER ・・・ 僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方 役に立つかもしれません グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』 P00BP いつも思うんだけど〜 パソコンが普及してない時代の開発環境ってどうやってたんだろ? ポケコンのようなマイコン書き込み機みたいなのあったんですかね? Ultrixあたりで普通にvi+dbxだったけど。 もちろん。 ただし、どのアーキテクチャか明記して、絶対に「質問」であること。 絶対値を求めるAbsProc()という関数をASMで作りました。しかしながら、期待した値が返ってきませんでした。 戻り値はC++の関数に実装しているのですが、他サイトで書いてあったコードを試したところ上手くいきました。 前者は自分が書いたコード、後者は他サイトに載っていたコード、内容が理解できません。 <base> AbsProc proc dwValue:DWORD mov eax, dwValue .IF eax < 0 neg eax .ENDIF ret AbsProc endp -- AbsProc2 proc dwValue:DWORD mov eax, dwValue cdq xor eax, edx sub eax, edx ret AbsProc2 endp -- </base> ちーがーうーだーろーおー DWORDは4バイトだから32ビットで合っている ただ、DWORDは符号なしなのでSDWORDに置き換えましたが結果は同じ(失敗)でした 前者の処理に問題があるのかな? 実行時に展開されるマクロとアセンブリ時に展開されるマクロを混同してないか 機械語のスレなのにマトモなレスが全部アセンブラ関連なのはなぜ? もっと機械語の質問しようぜ! Z80の話なのですが、 「オペコードがなぜこの順番なのか謎だったが ハード的に都合のいいように並んでいるのに気がついて震えた」 というようなコメントをどこかで見たのですが具体的にわかるかた教えてください レジスタやろ A B C D E H L (im) じゃなくて B C D E H L A (im) の方が都合が良かった ヘッダとかの諸元を書き換えたりは出来たとしても 普通に扱う動画は圧縮されてるから直接は触れない そしてそもそも機械語でやる必要など無い 機械語の初心者です 今に時代にマッチした入門書はありませんか?ぜご紹介いただけると嬉しいです! 過疎スレか、興味あったけど残念。 大昔486載せたPC手に入った時にコプロ(浮動小数計算)の使用に興味もったけど ネットもまだ無く関連書籍も知らず結局諦めた。 ニーモニックから内容は想像出来たけど、まずレジスタ自体どうなってるのかもわからんかったし。 例えばレジスタAXの値を1.03倍(当時の消費税?)をコプロで計算するにはどうやってたのかな? ググるとrbpはスタックのベースポインタみたいな解説が出てくるけどこれ本当か? とりあえず >rustc.exe -V -v rustc 1.66.0 (69f9c33d7 2022-12-12) binary: rustc commit-hash: 69f9c33d71c871fc16ac445211281c6e7a340943 commit-date: 2022-12-12 host: x86_64-pc-windows-msvc release: 1.66.0 LLVM version: 15.0.2 >rustc.exe --emit asm --crate-type=rlib -C panic=abort -C debuginfo=0 -C debug-assertions=no -C opt-level=3 lib.rs ってやって生成されるアセンブラリストを見てもプロシージャの頭でrspをrbpへコピーしたりはしていないし 自動変数のrsp相対のアドレスなんて事前に計算できるしそんな目的で汎用レジスタを専有するのはもったいない気もする ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる