アセンブラ初心者スレッド 2©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
2017/04/13(木) 17:35:55.70ID:1WMn3pSz
初心者OK!質問大歓迎!のアセンブラのスレッドです。
基本情報の勉強中の人、PICやH8を勉強中の学生などなど…

前スレ
アセンブラ初心者スレッド
http://echo.2ch.net/test/read.cgi/tech/1314502612/

関連スレ
アセンブラ 13
http://echo.2ch.net/test/read.cgi/tech/1314512680/
2018/10/01(月) 04:48:19.14ID:gNvpqBnl
>>336
LinuxのNASMとMASMは構文違うよ

NASMだと
mov rax, hogehoeg
マシン語は48 b8 xxxxxxxxxxxxxxx
これでraxにアドレスが入る

WindowsのMASMだと
mov rax, hogehoge
マシン語は48 8b 05 xxxxxxxx
hogehogeのメモリの内容がraxにロードされる
MASMの場合、
mov rax, offset hogehoge
これだとマシン語は48 b8 xxxxxxxxxxxxxxxx
これにしないとNASMのmov rax, hogehogeと同じマシン語にならない
2018/10/01(月) 05:43:56.26ID:gNvpqBnl
みんなはじめて読むMASMからやり直しだなw
2018/10/01(月) 05:51:48.63ID:gNvpqBnl
>>336
RIP相対32bitdispだとアクセスできない場合が出てくる
シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であって
アセンブラはその制限を受けない
実際にWindowsのEXEファイルは64bit絶対アドレスに対応してて
きちんと再配置してくれるわけだし
2018/10/01(月) 06:38:07.64ID:Z1gvrlLR
これこそアスペって奴だよな
質問とは関係ないCPU持ち出して勝手に「語り」をはじめたり、32bitでは1バイト短くなるだの
実用的には0.001%程度しか影響なさそうな絶対アドレスの方が速いだの、C/C++とリンクして使うのが
普通なのに「シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であってアセンブラはその制限を受けない」とか
初心者そっちのけで有害としか思えないような方法垂れ流したりと、他人の迷惑とか全く考えられないんだから

初心者にはMASMとNASMで同じように使えればそれで十分
完全に同じマシン語になるかどうかなんて知るか
特に絶対アドレスなんてWin64には不要と考えるべき
初期化領域以外の動的確保されたメモリはポインタ経由のアクセスが基本なんだから
2018/10/01(月) 06:45:27.19ID:Z1gvrlLR
>>334
こういう状態なんで、334は全く悪くないから気にしなくていいよ

アクセス違反を検出して対応するのは、使ってみたいところがあったのでちょうどいい機会だった
一応自分の書いたテストプログラムを上げとくね
https://pastebin.com/b5gZXxCF
2018/10/01(月) 06:51:19.23ID:gNvpqBnl
>>341
>>338が理解できないのか?
LinuxのNASMとWindowsのMASMは根本的に文法が違う
同じようにはプログラミングできないっての

MASMではMS-DOSの頃から伝統的に
mov ax, hogehoge
これをやるとhogehogeのメモリの内容をaxに読み込む
はじめて読むMASMにもそう書いてあるよw
2018/10/01(月) 07:02:13.01ID:gNvpqBnl
はじめて読むMASM
79ページ目
 データラベルは、マシンご命令のニーモニックのなかで、データを格納す
るメモリを参照するために使用することができます。次の図3−10をみてく
ださい。この図では、違いを対比させるために次節で解説するOFFSET擬似
命令の役割を併せて図解してあります。
 この場合、MESSAGEというデータラベルは01C3Hというアドレスに対応
しています。コードラベルの場合は、ラベル名がアドレスそのものと対応し
ていましたが、データラベルの場合にはちょっと違います。このことは重要
ですからよく覚えておいて下さい。
 たとえば、SYMDEBのようにアドレスを直接数値で指定する場合、そのア
ドレスのメモリの内容を参照するには、
 MOV DX, [01C3H]
のようにアドレスを[]で囲みます。これに対し、アセンブラのソースプロ
グラムでは、
 MOV
2018/10/01(月) 07:04:42.69ID:gNvpqBnl
はじめて読むMASM
79ページ目
 データラベルは、マシンご命令のニーモニックのなかで、データを格納す
るメモリを参照するために使用することができます。次の図3−10をみてく
ださい。この図では、違いを対比させるために次節で解説するOFFSET擬似
命令の役割を併せて図解してあります。
 この場合、MESSAGEというデータラベルは01C3Hというアドレスに対応
しています。コードラベルの場合は、ラベル名がアドレスそのものと対応し
ていましたが、データラベルの場合にはちょっと違います。このことは重要
ですからよく覚えておいて下さい。
 たとえば、SYMDEBのようにアドレスを直接数値で指定する場合、そのア
ドレスのメモリの内容を参照するには、
 MOV DX, [01C3H]
のようにアドレスを[]で囲みます。これに対し、アセンブラのソースプロ
グラムでは、
 MOV DX, MESSAGE
とします。このことからわかるように、データラベルはラベルに対応するア
ドレスそのものではなく、そのアドレスが示すメモリの内容を表します。
つまり、データラベルそのものを指定すると、アドレスの値を転送したり演算
したりする命令ではなくて、メモリに対して転送や演算を行う命令になりま
す。もう1度図3−10を見てじっくり確認してください。

こう書かれてる
346デフォルトの名無しさん
垢版 |
2018/10/01(月) 07:10:06.78ID:gNvpqBnl
82ページ目

3.6
OFFSET演算子とPTR演算子
OFFSET演算子
[書式] OFFSET ラベル名

データラベルをニーモニック中で使用すると、データ部分のアドレスでは
なく、データを格納したメモリの内容を表しますが、そのメモリのアドレス
はどうやって表すのでしょうか。図3−10で図解してあるので解説するまでも
ありませんが、データラベルに対応するアドレスは、次のように表します
 OFFSET データラベル
 OFFSET演算子は、ラベルに対して使用する演算子です。ラベルの前にこ
の演算子を付けると、ラベルに対応するアドレスを表す値となります。
 例題のプログラムでは図3−11の部分で使われています。これは画面に出
力するメッセージが格納されているアドレス値を、データとして定義してい
る例です。



MASMの文法は16bitの頃から一貫してる
みんなはじめて読むMASMからやりなおしだな
2018/10/01(月) 07:41:22.29ID:Z1gvrlLR
>>343
MASMでもmov al,[hogehoge]やlea rax,[hogehoge]が使えて、NASMと「同じ動作」が期待できて、
「根本的に」書き換えなくても疑似命令やマクロとかを書き換えれば移植できるってのがポイントで
NASMはLinux他とWindowsみたいなマルチプラットフォームのプロジェクトでよく使われてるから
あんたみたいなmov al,hogehogeやり方でNASMに移行すると変なバグに悩まされる可能性があんだよ
特にmov al,hogehogeがイミディエイトでアドレスの一部がコードされるのが酷い

SYMDEBで括弧で括るってのはイミディエイトと区別付かないからそうなってるんだろ
これはNASMで括弧で括るのと同じこと
時代遅れになった本の内容なんてどうでもいい
括弧で括らない表記は、8080時代を踏襲してるのか、インラインアセンブラでのCの変数参照と統一感があるってところだろう
これならNASMで異なる動作にならない方が無難

こっちが言いたいのは、初心者に有用なことが書けないなら「出てくんな」ってことだけ
2018/10/01(月) 07:55:48.93ID:gNvpqBnl
>>347
それは自分だけで書いたコードを読むだけならいいが
他人が書いたコードやコンパイラが吐き出したコードを読むのにはそれは通用しない
2018/10/01(月) 07:57:49.96ID:gNvpqBnl
それにNASMで慣れるとgccでインラインアセンブラを使うときに困る
gccはx86_64でもインラインアセンブラを扱えるのに
NASMの文法はgccのインラインアセンブラでは通用しないぞ
2018/10/01(月) 08:10:48.59ID:gNvpqBnl
多くの人がOFFSET演算子に対する理解がないようだから書いただけなのに
猛烈に反発してくる変な人がいるだけ

gccでは-mcmodel=largeのオプションを付けてコンパイルすると
movabs rax, offset flat: hogehoge
のような表現がよく出てくる
64bit絶対アドレスを扱うには必ず必要になってくる
2018/10/01(月) 09:35:33.25ID:Yquio+NL
>>341
アセンブラは、かなり細かいことを理解して無いと使いこなせないかもしれないよ。
それが C/C++ などとは違う点。

ちゃんと、リストファイルを見て、Intel の Instruction 表と照らし合わせて
どの命令が出力されているかを確認し、さらに、OBJやEXEファイルを逆アセンブル
してみて、さらにさらに、ローダーが実際にどのようにロードしたかをデバッガ
で確認する、などをちゃんとしないと、うまくいかないかもしれない。

実際、純正の Visual Studio が出したアセンブリソースが、masm で通らない
などという現象が確認されている事からしても、色々と確認作業が必要だと
思う。

自分はアセンブリ経験が豊富だが、上記のような確認作業をかなり積んだから
こそ使えていたと思う。

アセンブラの出力は、バージョンによっても違っていることがあるかも
知れないし、64BITモードでは、同じニモニックでも異なるマシン語を
出力することもありえる。

さらに言うと、アセンブラ自体が非常に困った仕様になってしまっていることもあり得る。

もともと、アセンブリ言語は、初心者が混乱無く使えるようにはなってないという側面もある。

失礼かもしれないけど、他の言語で豊富な経験を積んで、なおかつ、地頭のいい人限定だよね、もともと。
2018/10/01(月) 09:38:14.45ID:Yquio+NL
あと、一度実験した内容を正確に覚える記憶力も必要。

本で書かれていることと実際が違っていることは良くある。
2018/10/01(月) 10:13:48.86ID:Yquio+NL
>>334
例外処理については、詳細な文献と実験調査を行ったことがある。

文献だけでは不十分で、コードをフックするような仕組みによって実験しないと分からない。

教えることは出来るが、ここでは馬鹿にされるだけなのですまんが答えられない。
2018/10/01(月) 10:26:50.53ID:8+wJeq75
IDを換えながらレスをつけてるのか
2018/10/01(月) 23:50:29.17ID:Z1gvrlLR
>>353
Windows用のサンプルは>>342でupしてるので、Linuxは任せたw
2018/10/02(火) 07:08:08.55ID:+JdY6jxX
>>334
Windowsならちょっとググッただけでいろいろ出てくるぞ
このあたり見てやればできるのでは?
アセンブラは全く関係ないね

構造化例外処理
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/seh.html
GetExceptionCode
https://msdn.microsoft.com/ja-jp/library/cc428942.aspx
2018/10/02(火) 07:14:31.94ID:+JdY6jxX
あとこれも

構造化例外処理と UnhandledExceptionFilter
https://www.keicode.com/windows/windows_exception_handling.php
2018/10/02(火) 07:41:02.78ID:+JdY6jxX
これも

構造化例外処理 〜 例外情報の取得
https://www.keicode.com/windows/structured_exception_handling.php
2018/10/02(火) 08:43:48.77ID:+JdY6jxX
ただ、例外のハンドリングはできても、処理を続行するのは難しいね
EXCEPTION_CONTINUE_EXECUTION を返すと処理は続行されるけど
例外が発生するところから続行されるからね
例外が発生したところの次の命令から続行されるわけじゃないからね
2018/10/02(火) 14:17:43.67ID:kh21zWRr
>>359
次の命令からでも、続行する方法あるよ。
2018/10/02(火) 18:27:14.93ID:6jgE/r0r
アセンブラが難しすぎて読めません
https://gyazo.com/ba3099329df9872df87fa3c35ff13384
これはFPSの弾数周辺のアセンブリなんですが、どういう処理をしてるのか全く分かりません
どういう風に読んでいけば理解できるのか?ヒント下さい
ニーモニックは何となく分かるんですけど・・
362236
垢版 |
2018/10/02(火) 23:02:45.96ID:XopDtnD7
ありがとう。やりたいことはメモリマップドI/Oのエミュレーションです。なので呼び出し元のコードはなるべく細工したくありません

例外ハンドラでメモリを確保してしまうと2回目以降や隣接するアドレスのアクセス時に例外が発生しなくなってしまうので避けたいです
あとWindowsで>>334をやろうとした場合0x00001000から8Byteをあける必要がありますが、そのアドレスへデータをロードしないよう
MSVCのリンカへ指示する方法がわかりません
ldやlldなどであればリンカスクリプトで指示できるらしいのですが・・・(OSの候補にLinuxやFreeBSDがいる理由の一つです)

呼び出し元のコードに細工をすれば例外なんてめんどくさい物を使わずにすみますが、エミュレートしないケースの
オーバーヘッドを完全になくせるか心配です。コンパイラの最適化でインライン展開とデッドコード削除が約束されるなら
そっちの方が遙かに楽ですが・・・
2018/10/03(水) 00:49:48.02ID:/WqVKxM1
>>362
例外機構を使わずに、以下のような方法も場合によっては使える:

1. C++ の演算子の overload を使う方法。
2. Win32のメモリマップド I/O 機能を使う方法。



>あとWindowsで>>334をやろうとした場合0x00001000から8Byteをあける必要がありますが、
>そのアドレスへデータをロードしないよう
>MSVCのリンカへ指示する方法がわかりません

これは、VitualAlloc() で、0x1000 からの 1page(4096 バイト)をアクセス禁止の page に
すると可能。

ただし、8 バイト以外の部分もアクセス禁止になるので、その部分でも、例外ハンドラ
が起動してしまうので、その部分についての処理も例外ハンドラに書くようにする。
364デフォルトの名無しさん
垢版 |
2018/10/22(月) 19:17:19.32ID:3rTgJh0a
最近CASLU覚えた後、実際のマイコンのアセンブリ言語覚えたくてルネサスのRL78も覚えたんだけど(PICはCASLU以前から覚えてはいた)、
x86とZ80を合わせたようなニーモニックだけかと思ったらAをR0、XをR1って別名に出来たりAXがRP0に出来たり、GR0、GR1って書くCASLUにニーモニックが似てるんだが。。。

これってもしかして癒着とかじゃあるまいな。
(逆にルネサスがCASLUに寄せた可能性も微レ存)

日本車に使われてるらしいし、自動車は国の基幹産業だし(つまりルネサスのお得意様は日本の自動車メーカー)、あり得なくはない。
2018/10/22(月) 19:56:28.08ID:u6NjsIb0
仮想アセンブラでは、LLVM が標準
366デフォルトの名無しさん
垢版 |
2018/10/23(火) 14:50:58.07ID:yFsvvFWj
病院逝け
2018/10/23(火) 18:22:26.97ID:J6rCDaEz
もう少し髪が伸びたらな
2018/11/26(月) 21:11:44.08ID:gUboiJHI
LLVMネタってここで良いんですかね?
369デフォルトの名無しさん
垢版 |
2018/11/30(金) 09:46:12.16ID:+k7v6spR
アセンブラの勉強始めていきなり躓いてるのですが、オペランドの記述で
r/m32やimm32やr32やm32って何の略なんですか?
検索しても命令一覧表ばかり引っかかって・・(;´д`)
2018/11/30(金) 10:47:42.01ID:FCMY8z7v
r32: 32bit幅レジスタ
m32: 32bit幅メモリ
imm32: 32bit幅即値
2018/11/30(金) 10:53:47.90ID:HF1f08kq
命令の内部フォーマットとアドレッシングモード
https://www.mztn.org/lxasm64/amd05.html
2018/11/30(金) 15:33:43.72ID:m3TSK4YL
>>367
オシャレ
2018/11/30(金) 17:07:23.34ID:W1b9qzPZ
>>368
知ってても答えたくないかも。
2018/11/30(金) 17:26:55.55ID:u043vODt
>>365
あれは人間が読むコードじゃない
375デフォルトの名無しさん
垢版 |
2018/12/02(日) 03:55:19.52ID:5vpsWzUl
>>370
>>371
ありがとうございます!
2018/12/02(日) 13:54:11.82ID:vFBVENFT
LLVM 豆知識。
getelementptr には、似て非なるものが二種類ある。命令タイプと、定数タイプ。
後者は、他の命令のオペランドで用い、括弧でくくるような書き方をする。

仮想レジスタ %n に、整数定数を代入する命令が無い。
それで困った場合は、
 %10 = add i32 定数値, 0
などとすると良い。同様にポインタ定数も直接は代入できないが、
 %10 = getelementptr TYPE, TYPE * アドレス定数, 0
などとすれbな代入できる。
2018/12/02(日) 14:03:34.88ID:vFBVENFT
記憶に頼って書くと、

【命令タイプ】
%n =getelementptr TYPE, TYPE * 値, i32 idx1, i32 idx2, ・・・

【定数タイプ】
getelementptr (TYPE, TYPE * 値, i32 idx1, i32 idx2, ・・・)


getelementptr の他に、bitcast, itoptr, ptrtoi, ftoi, itof, zext, sext にも
全く同様に命令タイプと定数タイプがある。

この事は、Reference Manual には分かりやすくはかかれてないかも知れない。


また、話は変わるが、getelementptr は、配列のような概念を使うので、
アセンブラに慣れた人が、それを使うのが面倒な場合は、bitcast で i8* 型に cast
して計算する方法もある。

TYPE *ptr; に対し、

%R1 = bitcast TYPE * ptr to i8*
%R2 = getelmentptr i8* %R1, offset
%R3 = bitcast i8 * %R2 to TYPE*

とすれば、offset には、sizeof(TYPE) とは全く無関係の
バイト単位のオフセット値を指定できる。
2018/12/02(日) 14:16:20.44ID:vFBVENFT
記憶に頼って書く。

【getelementptr 豆知識】

getelementptr は、複雑なことをしているように見えるが、
 %n = getelementptr TYPE, TYPE * ptr, i32 idx
は、C 言語で書くと、
TYPE  ptr;
に対し、
%n = &(ptr[idx]);
を計算しているに過ぎない。

idx が2つ以上になって、
 %n = getelementptr TYPE, TYPE * ptr, i32 idx1, i32 idx2, i32 idx3
となった場合は、たとえば、TYPE が (n次元)配列の場合は、

%n = &(ptr[idx1][idx2][idx3]);

と同じ。覚えておくことは、アドレス演算子「&」が、最後にだけ付くということ。
この規則は構造体が中に含まれている場合でも全く変わらない。
2018/12/02(日) 14:24:12.50ID:vFBVENFT
言いたいことは変わらないが、TYPE が3次元配列の場合には、
TYPE *ptr; とは、厳密には、
ELEMTYPE (*ptr)[a][b][c];
となってるのだから、やりたいことは、
 %n = &(ptr[0][idx1][idx2][idx3]);
となる。だから、厳密に言うと、
idx を1つ増やす必要があり、
 %n = getelementptr TYPE, TYPE * ptr, i32 0, i32 idx1, i32 idx2, i32 idx3
となる。

規則性は、よく考えると分かる。
2018/12/02(日) 14:27:39.98ID:vFBVENFT
>>378
誤: TYPE  ptr;
正: TYPE  *ptr;
2018/12/08(土) 22:09:51.24ID:NuFUG+1u
LLVMのフロントエンドとバックエンドの自由度は極めて高い。CPUどころかGPUまである
ということはアーキテクチャAの実行イメージを入力に、アーキテクチャBの実行イメージを出力することも出来そう

と妄想した
2018/12/11(火) 15:12:16.55ID:TeIOtXwo
>>381
・Windows の EXE の場合、IAT、ILT、THUNK、DLL の名前解決などの LLVM への
 置き換えが果たして可能かどうか。これに関してはもしかしたら難しいかもしれない。

・COFF EXE の場合は可能かもしれないが、データ領域とコード領域を絶対に間違いなく
 区別する必要も有る。
383381
垢版 |
2018/12/11(火) 17:56:58.27ID:8tcWxISv
>>382
そういう動的な処理の多いシステムは難易度が高いと思うので、ゲーム機のROMイメージを別のプラットフォームで
実行できる実行イメージに出来ないかなと思った。一般的なエミュレータより高効率で動作させられるはず

と妄想した
384遠隔 MIPS フラッシュ書き込みテスト実験中
垢版 |
2019/02/23(土) 13:51:34.34ID:RfpPY2e5
MIPS アセンブラ初心者なんだけどおせーて?

asm volatile (“di %0” :“=r” (status));

って 割り込みを拒否して さらにstatusに現在の割り込み設定を退避させてるって意味でええの?
2019/02/24(日) 09:52:41.67ID:pcDSz9Pr
>>384
日本だと、8080, Z80, 6804(?), 68000, 8086, 80386(IA32) なら
答えられる人は少数なりにもある程度いるが、MIPSは難しいかもね、人数的に。
2019/02/24(日) 09:54:36.33ID:pcDSz9Pr
誤:6804
正:6809

多分、日本のパソコン文化の主流は、8080, Z80, 8086, 80386(IA32) だったと
思う。書くと反感買うと思うけど、少数派として、6809, 68000 があった、
という認識。
2019/02/24(日) 10:35:05.00ID:MroNHo4Z
6502....
388デフォルトの名無しさん
垢版 |
2019/02/24(日) 11:13:53.47ID:12/s8ZEO
>>385
そうなんだ

システムのプログラムフラシュ領域への自己書き込み

のインラインアセンブラシーケンスで使ったんだけど

プログラム追ってみたら割り込み許可情報のデータ退避して復帰してる感じだった

無事マイコンの自己プログラミングできた

ありがとう
389デフォルトの名無しさん
垢版 |
2019/02/24(日) 14:37:48.95ID:YwY0sV++
>>387
+1
変態め
2019/02/24(日) 14:42:53.37ID:/sgxXPqq
日本でMIPSだとプレステが有名だが・・・
2019/02/26(火) 17:30:06.50ID:8+gQOZAj
z80,68000,ia32 ならちょっとわかる
392デフォルトの名無しさん
垢版 |
2019/02/27(水) 15:03:03.39ID:ZopEvp0k
x86でNASMでELFを組んで学習しているのですが、_startの処理でstack frame設定の処理に質問があります
_startからジャンクデータを残さずEIP,ESPを整えて_exitを呼び出す方法を教えてください
(#立つ鳥後をEAX/EIP以外濁さず、を行いたい理由があります)
_exitはnoreturnで、int 0x80によるsystem_call()、又はSYSENTER(0f 34)によるia32_sysenter_target()
を用いて、SYSCALL_VECTOR又はMSR_IA32_SYSENTER_EIP(0x176)が呼ばれます
通常の_startにおけるlibcの処理では、auxvの中、AT_SYSINFO_HEDR(33)から、vDSO内の
__kernel_syscall_via_epcを経てカーネルへ向かうとの説明です
EXTERN _exit
GLOBAL _start
SECTION .text
_start:
push dword 42
call _exit
をnasm -f elf x.asm; gcc -Wall -s -nostartfiles x.o -o x.outで動きますが、
gccの方でlibgcc.a(-lgcc)やlibc(-lc)が自動で追加されるからなので、
-nostdlibや-nodefaultlibsではSegfaultします。ここの処理の理解のためにcrt0.oを眺めていると,
xor %ebp,%ebp ; stack frameの土台を用意
pop %esi ; [argc][argv][envp][auxv]... で一番上のargcをesiに
...(以下_libc_start_main処理)となり最終的に
sys_exit(int 0x80,eax = 1 (sys_exit),ebx = return code)が呼ばれていました
ソースを眺めると、$grep -r "NR_exit[^_]" /usr/include/
/usr/include/asm/unistd_32.h:#define __NR_exit 1
/usr/src/linux/include/uapi/asm-generic/unistd.h:__SYSCALL(__NR_exit, sys_exit)から
/usr/include/sys/syscall.hから
/usr/src/linux/arch/x86/kernel/entry_32.S:ENTRY(system_call)まで辿り着きましたが、
gdbでスタックを眺めてもいまいち要領が得ません
流れとして、stack->auxv[]->AT_SYSINFO_EHDR->VDSO32_vsyscall->__kernel_vsyscall->CUP依存のコピペ先へ
という理解なのですが…もしかして_start時のスタックの状況に勘違いがあるのでしょうか?
参考にしているのはA Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linuxです
393L
垢版 |
2019/02/27(水) 16:16:22.81ID:eSoS/w9e
>>392
直感からすると、原因は、esp に一度も値を設定していないことが最も疑わしい。
stdlib などがリンクされている場合、start up コードの中で、esp の値が
設定された後に、main などの自分のコードへと実行が移されるが、
-nostdlib などを付けた場合、リンク時に指定した entry point から
実行が開始される。今の場合、リンク時に entry point を指定していよう
なので、恐らく、最初の object file であるところの x.o の先頭アドレス
であるところの _start かr実行が開始される。

push dword 42 を行ったとき、esp の値が 0 か、または、0x7fffffff などの
値になっているため、segment fault や general protection fault などが
生じると思われる。

ここまでは全て記憶と直感に頼って書いた。
2019/02/27(水) 16:18:53.04ID:N0K9USfO
誤: リンク時に entry point を指定していよう
正: リンク時に entry point を指定しないよう


すまないが、あなたの書き込みの全部は読んでおらず、最初の方の
数行を見ての直感で答えた。
2019/02/27(水) 16:23:18.32ID:N0K9USfO
>>393
すまん。

esp だけでなく、ss の値も重要。
mov ax,ds
mov ss,ax
などとした方がいいかもしれない。

一番重要なのは、_start: の直後あたりに、

mov esp, (何らかのメモリバッファの底のアドレス)

とする事。メモリバッファは、自分で用意する。
アセンブラ初心者なら、masm なら、db 命令などで領域を静的に
確保し、その最後のアドレスあたりを指定すると良い。

なお、esp を設定するまでは、push, pop, call は行ってはならない。
396L
垢版 |
2019/02/27(水) 16:37:51.36ID:eSoS/w9e
>>392
「x86」と言っても、OS によって変わってきて、Windows などなら、確か、
ライブラリを全くリンクしない場合でも、最初から esp は、一応、
「使える状態」に設定されていたと(心の中に)記憶している。
つまり、esp は、最初からOSが用意した何らかのメモリ・ブロックの底に
設定された状態で exe の実行が開始されると思う。

組み込みなどでは、esp の値は 0 みたいな値になっているかもしれない。
397L
垢版 |
2019/03/04(月) 12:10:03.33ID:yv8DGU0u
>>392
gdb が使える状態なら、
・レジスタ ss, esp がちゃんと「正しい」値になっているかチェックする。
・ss == ds なのか、ss = 0 なのか、ss は 0 ではないか、ds とは別の値なのか。
・call _exit の部分の飛び先アドレスがちゃんと正しい相対アドレスになっているか
 確認する。---> 正しくリンクされていない場合もあるため。

_exit 関数が shared library の中にあるような場合、処理系によって call 文がどのような
マシン語になるかは変わってくる場合がある。リンカが、call [addr] 形式の indirect call
を想定する場合と、
call import_func
・・・
import_func:
jmp [_exit_entry]
・・・
_exit_entry dd _exit

などのようになる場合など、さまざま。それが正しくなっているかの確認も必要。
2019/07/04(木) 19:46:17.60ID:JhnD4djU
今時のIA32コードを吐く処理系がよく使う命令についてのまとめた資料ってないですかね
486DXあたりでもかなりの命令数になりますが現行で使われている命令は限定されますよね?
399デフォルトの名無しさん
垢版 |
2019/07/05(金) 11:29:01.09ID:SLYFNUzn
>現行で使われている命令は限定

何言ってんだ
2019/07/05(金) 19:14:34.33ID:lm712Ojq
x86系は現行のアーキテクチャとしては間違いなくカオス組。解析器とか作りたくねー
2019/07/21(日) 02:41:27.70ID:jI92lOqS
intelで公開している奴じゃなくて?
2019/10/06(日) 15:58:10.24ID:xhkeezXX
x86 の条件付きジャンプ命令

JG Greater
JL Less
JE Equal
JNE Not Equal
は分かったのですが、
JA
JB
は何の英単語の略なんでしょうか?
2019/10/06(日) 16:06:45.50ID:wxDvIEUu
aboveとbelowだったかな
2019/10/06(日) 17:14:52.78ID:xhkeezXX
おお、なるほど!
素早いご回答ありがとうございます
2019/10/06(日) 17:29:21.50ID:xhkeezXX
https://codeday.me/jp/qa/20190731/1353200.html
おかげさまでこちらのページを見つける事ができました
間違いないようです
406デフォルトの名無しさん
垢版 |
2019/10/06(日) 17:30:39.06ID:pvG0vkV+
昔は常識だった
2019/10/21(月) 09:51:46.99ID:J3DzZudC
アセンブラ買ったらリファレンス一冊ついてたしな...
今ならintelのpdf先に見る所?
2019/10/24(木) 10:43:50.55ID:AtkMQyN4
古いのなら日本語マニュアルあるぞ

インテルエクステンデッド・メモリ64テクノロジ・ソフトウェア・デベロッパーズ・ガイド第1巻
インテルRエクステンデッド・メモリ64テクノロジ・ソフトウェア・デベロッパーズ・ガイド第2巻

直リンクはちょくりんNGで貼れないのでググッて
2019/10/24(木) 10:52:31.09ID:AtkMQyN4
なんで5chでNGワード扱いされてるんだろうな
全部全角にしてみた

https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL1_30083402_i.pdf
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL2_30083502_i.pdf
410デフォルトの名無しさん
垢版 |
2019/10/24(木) 11:01:40.57ID:ABhN6CSm
EM64T_VOL1_30083402_i.pdf
EM64T_VOL2_30083502_i.pdf

どうみてもこれで充分です
ほんとうにありがとうございました
2019/10/24(木) 11:12:11.26ID:AtkMQyN4
英語のマニュアル
https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf
2019/10/25(金) 15:41:34.61ID:4V9sCl2t
>>406
8086のアセンブラと言えば、PC-9801とBASICやMS-DOSの組み合わせだが、
当時パソコンを持っていた人はBASICは知っている人が多く、C言語は
好き物が理解していたが、アセンブラまで理解している人は稀で、
ja の a が above であることを知っている人はごく一部だった。
413デフォルトの名無しさん
垢版 |
2019/10/25(金) 16:36:39.41ID:BNTJ335Q
>アセンブラまで理解している人は稀

あほすぎ
お前のまわりがそうだっただけだろ
2019/10/25(金) 17:38:11.71ID:UlVp4BAq
>>412
当時、The BASICやASCIIでBASICとアセンブラで組んだゲームが山ほど掲載されてた。
同じことをしたいと思ったら8086のアセンブラ知らないとどうしようもなかったんだよ。
BASICはエラー出しても止まってくれたけど、アセンブラでエラー出すとそのままマシンが固まったり
勝手にリブートしたりして何度も泣いたもんだ。けど同時に非常に面白かった。
アセンブラで「どこか1カ所でもミスったらマシンが飛ぶ」と思ったら緊張感がハンパない。
「これで絶対動く」という確信が持てるまで何度も見直してから、震える指でエンターキーを押して
動いたときの感動。立ち上がって全身でガッツポーズしたね。
プログラミングの醍醐味はこれだよ。これ覚えたらもう止められない。
2019/10/25(金) 18:16:12.88ID:4V9sCl2t
俺自身はアセンブラは使ってたよ。
しかし、一般的にはそんなに使われている訳ではなかった。
プロのゲームプログラマやそういう雑誌に掲載されたゲーム作者は使っていたが。
そういう人たちは特殊だったので、天才プログラマなんて言葉が生まれた。
2019/10/25(金) 18:21:42.17ID:4V9sCl2t
>>414
そういうことを言うと、当時を知らない人はアセンブラなんて誰でもやっていた
などという嘘を信じてしまう。
2019/10/25(金) 21:14:38.60ID:UlVp4BAq
>>416
誰でもやってたなんて言ってないんだが。やってた人もけっこういたって程度だろう。
もっと正確に言うなら、当時プログラムをやってた人の総数と、そのうちアセンブラをやってた人が何割いたか
という統計データでも探してこないと正確な割合は出ない。
ただ、そういう本が何冊も出てたってことはそれだけ売れてたってことだから、程度の差はあれ、
アセンブラに興味があった人がそれなりにいたことは間違いない。
2019/10/25(金) 23:59:54.86ID:tDdAcA6n
>>417
ja の a が above の意味であることは知っていても、ja が直前の cmp 命令と
組み合わせて使うことや、グラフィックを描くにはG-VRAMと呼ばれる場所に
数値を書くということまでちゃんと理解できた人が少なかった。
2019/10/26(土) 02:40:13.17ID:gJ3xyH9v
>>418
PC雑誌、アセンブラのドキュメントと初級解説本、9801の解析本くらい読めば普通に書いてあった。
2019/10/26(土) 02:52:45.09ID:dcsgYCXg
>>419
今現在、プログラミングしている人の大部分は、スクリプト言語しか使えない
と言われている。その理由は、ポインタが理解できないから。
ポインタが理解出来ない人は、アセンブラの間接参照 [reg + addr]
も理解できないだろうから、アセンブラではグラフィックもまともに描けない。

当時の常識といっても、今のパソコン使いが当時にタイムスリップしても
大半はアセンブラを理解はおろか使いこなすなど出来ない。
421デフォルトの名無しさん
垢版 |
2019/10/26(土) 09:59:09.07ID:e6NVGnmw
>>417
>当時プログラムをやってた人の総数と、そのうちアセンブラをやってた人が何割いたか

今より遥かに高い割合で居ただろう
2019/10/26(土) 18:30:52.81ID:gJ3xyH9v
>>420
一般の人はアセンブラなんて見たこともないだろうから別にそれはそれでいい。
プログラマーだってアセンブラが使いにくいからC使ってるわけだし。
ただ、アセンブラやっとくとCPUの動作が直にわかるし、簡単なプログラムでも超高速に動く。
Cからアセンブラコードを生成して、内部でどんな処理してるか調べることもできる。
そういうところが面白いと思う人がやればいいんだよ。
2019/10/26(土) 22:35:07.76ID:3WWCBV2x
CASL2の話題はこのスレでしていいですか?
2019/10/27(日) 02:06:55.94ID:LkxSYXiy
上の流れ見るに90年代が華の野郎共の巣だから2はわかんないかも(笑
425423
垢版 |
2019/10/27(日) 10:41:06.65ID:MlUkQFx6
>>424
気になりませんよ
ありがとうございます
426デフォルトの名無しさん
垢版 |
2019/10/27(日) 11:40:07.17ID:CbvQpcn+
試験科目LLVMにすれば良いのに
2019/10/27(日) 12:56:27.43ID:duBk5x4n
普通にゲームしかやらんやつの方が多かっただけで
できるやつが少ないかったのは事実
2019/10/27(日) 17:04:26.06ID:GpjOYffU
>>427
比率で言えば大体黄金比(2:6:2)になる。昔も今もプログラマーで本当にできるのは上位2割、
全く向いてないのが下の2割、まあまあ普通なのが真ん中の6割。
スクリプトしか書けないのはこの6割の中に入る。上位2割はスクリプトなんてちょっとやればわかるから
何とも思ってない。文字通りレベルが違うから話も合わない。でもそれでいいんだよ。
2019/10/27(日) 17:50:07.64ID:9Kmf+J9a
最も利用率が高いのはRubyだが
マイコン相手にすればアセンブラとにらめっこだし
気に入らないが必要とあればC/C++やPythonやJavaScriptも触る
2019/10/28(月) 09:34:47.25ID:SaUE9md3
80年代はアセンブラ関連の書籍がたくさんあった
Z80、6809、8086、68000
まだ1989年頃まではCコンパイラが高価だったりして敷居が高かったし
BASICやってた人は高速化するにはマシン語を使ってたしな
アセンブラやマシン語初心者向けのBASICから使えるマシン語の本もたくさん出てた
アセンブラやマシン語を使ってゲームを作る本とかな
電子工作関連でもZ80のアセンブラや周辺LSIのプログラミングで初心者向けの本がたくさんあった
アセンブラ覚えるなら1980年代や1990年代初め頃の方がずっと恵まれてたな
図書館の蔵書とか検索してみるとそういう古い本が出てくるかもよ
2019/10/28(月) 09:46:48.07ID:SaUE9md3
今と違って1980年代中ごろまではBASICがメインだったし
ゲームしかやらない人を除けば1980年中ごろまでのパソコンユーザは
プログラミングができるのが当たり前だった
だからパソコンユーザの中でアセンブラもやってた人は多かったよ
そもそもパソコンを扱える人自体が今と違って少なかった
プログラミングに興味がない人はそもそもパソコンにも興味がなかったからな
2019/10/28(月) 09:58:42.55ID:SaUE9md3
>>416
当時はパソコンを趣味としてやってる人自体が少なかった
パソコンに興味のない普通の人はキーボードなんて叩いて何が面白いのとかそういう認識
パソコンなんてわけのわからないそんなつまらないものなんでやってるのって感じ
そういう感じなんでパソコンユーザは根暗とかオタクとか言われて馬鹿にされてたからな
2019/10/28(月) 10:04:22.32ID:SaUE9md3
>>427
そのゲームが一番アセンブラやマシン語を必要としてたんだよな

当時、雑誌にゲームを投稿してた人のインタビュー
https://akiba-pc.watch.impress.co.jp/docs/sp/1213044.html
2019/10/28(月) 10:06:00.01ID:SaUE9md3
マシン語 ゲーム
この2つのキーワードで検索してみると80年代のアセンブラやマシン語の本がたくさん出てくる
435デフォルトの名無しさん
垢版 |
2019/10/28(月) 15:42:16.95ID:CizzAz3Z
>ゲームしかやらんやつの

ゲームで遊んでた人と
ゲームを造ってた人を
意図的に混同してるだろ

しかもそもそもマ板の話題だし
ム板でするな
2019/10/28(月) 15:55:47.51ID:jVNnMdKT
>>431
アセンブラは、本を買ってみたりした人は多かったかもしれないが、
実際に使いこなすまでにいたった人は稀だったはず。
だから、アセンブラやマシン語は難しいという認識だった。

なお、ちょっと話がずれるが、LLVM は、型の部分が煩雑で普通のアセンブラよりも
難しい部分がある。
構造体型を使わなければ普通のアセンブラと同じように出来ないことは
ないが、それでも、bitcast などを頻繁に繰り返す必要がある。
なお、構造体型をヒントに最適化している可能性があるので、面倒でも
構造体型を使う必要があるかもしれない。
上手く整理して理解しないと、コンパイラを作る人泣かせになる。
2019/10/28(月) 19:16:09.04ID:jHTeibRQ
80年代後半だが電子系の学生なら講義でZ80のアセンブラやらされてな
2019/10/28(月) 21:16:27.78ID:6rYZFXXL
RAM640KBでCとかほぼ無理だろ
X68000でも4MB以上推奨だった記憶
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況