2018年10月05日

Sjasm 0.42cを64ビット環境でコンパイル

(※2018年10月6・10日追記)
最後に、64ビットでコンパイルする方法は今のところ不明、と書いたがコンパイルできたわ。
台風25号吹き荒ぶ真っ只中にな!

(※パッチが新しくなりました、下記のバグも修正されます。)
http://akifuyu.sakura.ne.jp/blog/binary/sjasm-0.42c-amd64fix.patch

需要ないとは思うが、パッチを置いとく。
このパッチを適応すると、ついでに下記inline関連もプランC方式で修正される。

公式からsjasm42c.zipを拾ってきたら適当なディレクトリを作ってこの中に解凍し、上記パッチもここに保存する。
次にこのディレクトリに入ってパッチを当てる。

$ patch -p1 < sjasm-0.42c-amd64fix.patch

パッチを適応したら、ディレクトリsjasmsrc42cの中に入り、

$ make

で、同ディレクトリ内にsjasm実行バイナリが作られます。
何度も動作テストはしたので、多分問題なく動くと思う、多分。。。

原因は、rawsource.cpp内でfindの結果をunsigned intで格納した変数とstring::nposを比較しているところがあり、64ビット環境だと正しく比較できなくなっていたのが原因でした。
この結果、-1をsubstrに放り込んでコアダンプ吐いてました。
真面目に修正するとめんどくさすぎるので、該当if文をpos==(unsigned int)string::nposとして適当に修正した、この際なんでもいいから動けば正義なんだYO!

エラー内容から原因は考えついていたので、比較的簡単に修正できた。
修正の仕方の良し悪しは別として。
エレガントは修正は、海外のエロいハッカーにお願いしたい。

(※2018年10月10日追記)
半角カナを食べさせるとフリーズすることがある。
まあイレギュラーな文字だし、海外のソフトだし、と誤魔化そうと思ったけど結局修正してみた。
日本の8ビットPCは半角カナとか多様するからね、うん。
前述のパッチを当てると、このバグも修正されます。

このバグの原因は、特定の文字列をチェックする際に256バイトの配列を作り、該当アスキーコードの位置をtrueに、それ以外をfalseとして、チェックする文字列の一文字をこの配列の該当位置から有効か無効かを調べています。
しかし比較する文字の変数がsigned charであるため0x80を越えるアスキーコードを正常に調べることができない状態でした。
パッチでは該当の変数をunsigned charでキャストすることで対処しています。


(※以下旧記事)
近年のリバイバルブームに乗って、おいらも当時に作ったPC-8801のどうでもいい感じのソフトを一から作りなおしてます、そのうち公開予定です。
で、制作に使うアセンブラにはSjasmを使っています。

http://xl2s.tk/

シンプルで使い勝手がいいんです。
いいんですが、Fedoraのリポジトリにあるバイナリ0.39g1は、困ったことにmodule使うとセグフォ吐いて落ちてしまい使い物にならず。
そこで、公式にある0.42cをダウンロード、こちらは修正されてる。
付属のDebian用バイナリはFedora 29でも普通に動く。
けれど、ソースをコンパイルすることにしたのだが、トラブル満載。
リンカがundefined referenceを大量に吐き、これを乗り越えてもコアダンプ吐いて落ちるわな。

と、いうわけで、これ使いたい人もいないと思うけど、コンパイル手順。
パッチ作ろうと思ったけれど、解法が多岐に渡るため断念しました。
(※追記:パッチを用意しました)

*共通
sjasm.hを修正
ソースの適当なところ、68行目の#include の直下辺りにでも、

#include

を、追加。
Makefileも修正。
CXXFLAGSとLDFLAGSに-m32を追加、Sjasm 0.42cは32ビットでないと動かないっぽい。
前段階に、32ビット版のglibcをインストールしておくこと。

以下、お好きな方法で修正。
*個別の修正・プランA
reader.cppの79行目にある

inline void skipblanks(string &p) {

単純にinlineのところを除去する。
パフォーマンスは落ちるかも。

*個別の修正・プランB
MakefileのCXXFLAGSのところに、-fkeep-inline-functionsを追加。

CXXFLAGS = -O2 -m32 -fkeep-inline-functions

な感じにする。
問題は起きない、と思う、多分。

*個別の修正・プランC
reader.cppの79行目から始まるskipblanks関数をヘッダに引っ越しさせて、
ヘッダにあるプロトタイプ宣言と一緒にstaticをつける。

static inline void skipblanks(string &p) {

こんな感じ。


どの手を使うにしても、結局のところ付属のバイナリ使うのが正解だと思う。
なお、64ビットでコンパイルする方法は今のところ不明。

他に使い勝手がいいZ80アセンブラがあればいいんだけどね。
z80asmはおいら的にイマイチだったので使用を断念。
posted by えとかみ at 21:45| Comment(0) | TrackBack(0) | パソコン