アセンブラ初心者スレッド 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/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以上推奨だった記憶
2019/10/28(月) 23:13:33.30ID:dYdO5Ttk
>>430
書籍もそうだが、i486 の時代になっても ms-dos が動き、プロテクトモードは自由に触り放題、というのが当時はすばらしかった
今はプロテクトモードは触らしてもらえない、マシン語化する価値があるものは、キャリーフラグを触れば速くなるもの、くらいしか思いつかない
2019/10/29(火) 01:38:16.40ID:axC2qBNh
>>438
当時、Turbo C などが結構使えていた。ところが、リアルモードや
仮想86モードのx86には、640KBの壁ではなく、64KBの壁があった。
それがかなり問題だった。
2019/10/29(火) 01:52:33.06ID:axC2qBNh
>>439
>今はプロテクトモードは触らしてもらえない、
最初からOSがプロテクトモードにしてくれている。

MS-DOSで自力でプロテクトモードにするのはかなり大変だったのでずっと
楽になってる。というのは、プロテクトモードにした場合、DOS
は、仮想8086モードで動かさないといけなかった。しかし、そうするためには
非常に膨大なプログラミングが必要になった。仮想8086モードは、設定すれば
すぐ動くわけではなく、割り込みテーブルなどを全部自分で用意しなければ
ならなかったから。割り込みテーブルもテーブルを用意すれば終わりではなく、
ほとんどエミュレータの作成をしてる感じで、32BITプログラムを用意して、
16BITコードでsti,cliやint命令なんかが実行されるたびに、エミュレーション
ハンドらが起動されて、そこでしかるべき処理を行う必要があった。
だから、自力でDOSをプロテクトモードにするのはほとんど不可能で、
DPMIやVCPIという既存のプログラムが利用された。
しかし、それらをまともにつかうのは、TURBO C++などの16ビットコンパイラ
では無理だった。
2019/10/29(火) 02:03:23.94ID:axC2qBNh
>>441
DOSで32BITアドレッシングを使うのは、非常に複雑で、80386系CPUの
欠陥か、または、Windowsを売るためにわざとDOSでは32BITアドレッシング
を使いにくくしていたかのどちらかと考えられる。
DOSにおいても、32BITレジスタは簡単に使うことが出来たので、32BITデータ
を読み込んだり32BITで加減乗除を行うのは簡単に出来た。ところが、
アドレスを32BITにすることは原則的にはできなかった。
既に、EMSメモリを使うために、プロテクトモードは使われてしまっており、
DOSは仮想8086モードで動いていた。そのせいで、自作プログラムで勝手に
プロテクトモードをコントロールすることは不可能だった。
というのは、プロテクトモードは、最初にそれを行ったプログラムが
支配者の様になり、他のプログラムは、支配される側としてしか動作できない
仕組みになっていたから。だから、EMSメモリ用の「支配する側のプログラム」
が対応していない限り、支配される側の一般プログラムは、32BITアドレッシング
を使うことは出来なかった。

そのために容易されたのが、VCPIとDPMI。ところが、まともに32BIT
アドレッシングを使うのはVCPIでは難しかったが、DPMIに対応したEMS
ドライバは限られていた。しかも、DPMIを使うにはC/C++コンパイラもそれに
対応していなくてはならなかった。それで、結局、DOSで32BITアドレッシング
を使ったアプリは非常に限られたものとなってしまった。

それが、Windowsが使われた一つの理由、Windowsは、最初から32BITアドレッシング
が使えるようになっていたから。実は、Wintel同盟なるものがあり、恐らく
DOSでは32BITアドレッシングを自由には使えなくするために、80386系CPU
をわざと変な風に設計したのではないかと疑っている。
一般の人は、そんな裏事情を知らない。
2019/10/29(火) 07:05:18.63ID:Zl5vhLEl
DOSでは京都マイクロコンピュータが
DOSエクステンダーのEXE386を非商用で実費で配布しててパソコン通信で無料で配布
商用でも1000コピーで100万円くらいで売ってたがそれに対応したコンパイラが高価だったな
海外ではDJCPPがあったが日本ではあまり普及しなかったし、商用ソフトでは使われなかった
唯一の例外はFM-TOWNS
初めからDOSエクステンダーが組み込まれて32bitのDOS環境が使えた
公式のアセンブラが非常に高価でCコンパイラもその高価なアセンブラが必要で
一般ユーザには普及しなかったがFM-TOWNS用にDJCPPが移植された
そのTOWNS用に移植されたDJCPPがEXE386を使うことでPC-98でも使えたが
PC-98ではあまり普及はしなかった

DOSで32bit環境が整ったのがWindows 95が発売される直前
Borland CやWATCOM CなどでCコンパイラにDOSエクステンダーを付けて販売するようになったが
Windows 95が出てみんなもうDOSには興味がなくなっていた

>>442
Windows 3.1まではまだセグメントの64KBの壁があったけどね
Windows 3.1用に32bitのフラットなアドレスが扱えるWin32sが出たね
Win32sはあまり普及はしなかったが
2019/10/29(火) 07:09:00.71ID:Zl5vhLEl
DJCPPじゃなくてDJGPPだった
2019/10/29(火) 07:24:26.40ID:Zl5vhLEl
アセンブラに話を戻すと
DOSエクステンダーのEXE386はMASMの5.0以上やTurboAssemblerなどのアセンブラで
EXE386上で動作するアプリを作れた
プロテクトモード上の特定のアドレスにVRAMがマッピングされていたので
VRAMへのアクセスも容易だったな

そのEXE386は今でもベクターからダウンロードできる
2019/10/29(火) 17:54:53.05ID:VnX4qZP9
>>445
当時、ほとんどのアプリは基本ロジック部分はC/C++言語で書いていて、
グラフィックなどの速度が必要な部分をアセンブラで書くということをやっていた。
だから確かにアセンブラからは32BITアドレッシングは可能であっても、
C/C++が使えなければ現実的に使うことは無理であった。
だから、何らかのC/C++コンパイラが必要となった。それが結構高価であった
ことと、既にWin95に一般民が移行していたので選択の余地は狭かった。
ただし、移行というより、1995はパソコン元年などといわれたくらい、
初めてパソコンを使い始める大挙して押し寄せた。
だから、DOSエクステンダは魅力的ではあっても、その流れに逆らうことは
難しかった。
2019/10/29(火) 18:03:50.25ID:I2MyCbhZ
俺の質問めっちゃ低レベル…

LDやSTなどの命令やオペランドは主記憶に記憶されることは分かったんですが、
コメントも同様に、オペランドとかの後に記憶されているんですか?
2019/10/29(火) 18:11:29.42ID:n7hbVS5F
>>447
一般的な処理系ならコメントはアセンブル時に削除される
2019/10/29(火) 18:48:08.61ID:ex5BLs+R
今でもはじめて読む8086読んどけかと思えば絶版なのかな...amazon在庫無いね
2019/10/29(火) 19:01:39.60ID:Rxtcy1tm
>>441
>プロテクトモードにした場合、DOSは、仮想8086モードで動かさないといけなかった。
いいえ、リアルモードで DOS を起動して、ユーザープログラムが勝手にプロテクトモードに変更してなんら問題ないですよ
プロテクトモードから一時的にリアルモードに戻ることはできませんが、プロテクトモードで割り込みテーブルを再設定すれば問題ないですね

>自力でDOSをプロテクトモードにするのはほとんど不可能で、DPMIやVCPIという既存のプログラムが利用された。
まあそれは事実ですが、あと DOS エクステンダーがよく使われましたね
2019/10/29(火) 19:02:55.89ID:Rxtcy1tm
>>442
>既に、EMSメモリを使うために、プロテクトモードは使われてしまっており、
>DOSは仮想8086モードで動いていた。そのせいで、自作プログラムで勝手に
>プロテクトモードをコントロールすることは不可能だった。

EMS なんて非常に使いにくいものはさっさと追放しちゃえばよかったのですよ
2019/10/29(火) 19:03:56.60ID:Rxtcy1tm
>>442
>DOSでは32BITアドレッシングを自由には使えなくするために、
66 プレフィックスか 67 プレフィックスで無問題だったかと
2019/10/29(火) 19:36:42.19ID:QynZyw6q
まず
80286ではプロテクトモードからリアルモードに戻ることが出来なかったため
戻るために特殊な仕組みが必要になり、プロテクトモードが非常に使いにくかった

386以降は、単純にリアルモードに戻ることが可能になったため使いやすくなり
セグメントのリミットを設定し直してそのまま戻ることで
リアルモード(DOS)から4G全てにアクセスすることも出来るようになった

そして、仮想86モードでの割り込み処理も、別に複雑な処理などは基本的には必要ない
なぜならBIOSにある、元の割り込み処理ルーチンに処理させれば良いだけだから
もちろんIDTをセットアップして処理するプログラムは用意する必要はあるが
大半はスタックにあるリアルモードでの戻り番地等を設定して、
あたかもリアルモードで割り込みが起こったかのようにBIOSやDOSの割り込みベクタテーブルのアドレスに飛ぶだけ

自前で処理する必要があるのは、GPフォルトやページフォルト、
それにA20の操作の処理が入ったらページテーブルを書き換える等するだけ
その程度でも、HMA64KやUMBを用意して空きメモリに余裕があるDOSを動かすくらいなら出来た
(ただし、DMAにも対処するにはまた別途処理が必要)

もちろんEMS等に対応するには、そのための処理ルーチンを用意する必要があるし
EMSやVCPI程度ならともかく、DPMIにも対応するとなると、かなり面倒くさかっただろうとは思う
454447
垢版 |
2019/10/29(火) 19:46:30.39ID:I2MyCbhZ
>>448
ありがとうございました
ちょっとショックです…
2019/10/29(火) 21:10:57.31ID:KWhI3UgV
>>449
Amazonに「64ビットアセンブラ入門」というのがある。
2019/10/29(火) 21:13:34.56ID:KWhI3UgV
>>454
コメントは実行に関係ないから削除されて当たり前なんだが、
それがショックという意見は始めて聞いた。なぜ?
2019/10/29(火) 21:41:39.59ID:KWhI3UgV
アセンブラでガリガリ書きたい人は、フルアセンブラで書いたOSがある。
プログラムもアセンブラで書く。サンプルプログラムもたくさんある。
DOSのように終わったOSではないので、今のPCにもインストールできる。
Kolibriは初期のMenuetからフォークした32bit OS。Menuetは64bit。
面倒なアドレッシング制限もなく、画面表示も簡単にできる。
日本語にはまだ対応していないので、誰かが日本語化すればユーザが増えるかも。

menuet os
http://www.menuetos.net/

kolibri os
http://kolibrios.org/en/index
2019/10/29(火) 21:48:10.11ID:VnX4qZP9
>>452
そのプリフィックスは、データ用とアドレス用のものだけど、
データ用の方はどのモードからも普通に使えた。ところが、
アドレス用の方はプロテクトモードでしか使えず、
仮想8086モードでも使用不可能になっていた。
それが、Wintel同盟がDOSを使えなくしてWindowsだけを使えるように
するための策略だったのではないかと疑っている
(そんな風に設計する理由は特に無かったのに。)。
2019/10/29(火) 22:01:50.22ID:VnX4qZP9
>453
>そして、仮想86モードでの割り込み処理も、別に複雑な処理などは基本的には必要ない
>なぜならBIOSにある、元の割り込み処理ルーチンに処理させれば良いだけだから
>もちろんIDTをセットアップして処理するプログラムは用意する必要はあるが
>大半はスタックにあるリアルモードでの戻り番地等を設定して、
>あたかもリアルモードで割り込みが起こったかのようにBIOSやDOSの割り込みベクタテーブルのアドレスに飛ぶだけ

ここは言うほど簡単ではなかった。まず、32BITモードから仮想8086モードの
サブルーチン(割り込みハンドラも)を呼ぶ方法がcall命令としては用意されて
いなかった。だから、32BIT--->V8086モードへは、call命令から帰るリターン命令
の一種であるところのiret命令を使わなくてはいけなかった。その設定が細かい話
になるので細心の注意が必要であった。さらに、V8086--->32BITモードの
呼び出し元へ戻る際には、ret命令ではなく、コールゲートに対する特殊な
call命令か、int命令を用いなくてはならなかった。しかし、もともとのDOSの
割り込みハンドラの最後の部分にはそんな命令が書かれているわけは無いので、
工夫が必要であった。割り込みハンドラから戻ってくるアドレスに、
コールゲートに対するcall命令か、32BITモードに対するint命令かを
「仕掛けて」おく必要があった。どっちにしろ、それはもともと戻るための
命令ではないものを戻る命令として用いているので、スタックなどをきちんと
戻すためには細心の注意が必要だった。
さらに、二重に割り込みが入ったような場合に対応させるためにも、
非常に注意深くスタックの構造を設計しておく必要があった。それは、
32BITモードと16BITモードスタックのの二重構造だった。というのは、
80386のスタックは、32BITモードと16BITモードで全く別の領域を
使う仕組みになっていたので、連続的にすることはできなかったためである。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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