初心者OK!質問大歓迎!のアセンブラのスレッドです。
基本情報の勉強中の人、PICやH8を勉強中の学生などなど…
前スレ
アセンブラ初心者スレッド
http://echo.2ch.net/test/read.cgi/tech/1314502612/
関連スレ
アセンブラ 13
http://echo.2ch.net/test/read.cgi/tech/1314512680/
アセンブラ初心者スレッド 2©2ch.net
レス数が1000を超えています。これ以上書き込みはできません。
2017/04/13(木) 17:35:55.70ID:1WMn3pSz
2017/04/13(木) 17:41:03.83ID:m/ZfxtWH
>>1
乙
乙
3デフォルトの名無しさん
2017/04/13(木) 18:14:24.24ID:VLmLig3K v3
4あぼーん
2017/04/13(木) 18:15:04.12ID:Gon4S40X あぼーん
5デフォルトの名無しさん
2017/04/13(木) 18:15:32.34ID:VLmLig3K 終了
7デフォルトの名無しさん
2017/04/13(木) 19:43:03.43ID:VLmLig3K asm.js とかさ
LLVM とかさ
このスレで扱っても良いと思うのね
LLVM とかさ
このスレで扱っても良いと思うのね
2017/04/13(木) 20:44:33.86ID:nESB199J
ごもっともですわ
2017/04/13(木) 21:26:38.34ID:J4z4l4hW
うん需要ある?
2017/04/14(金) 08:40:42.32ID:sKcRbeeD
組み込みでなら多少は。
2017/04/14(金) 10:04:28.48ID:L6e5ZQwW
あ。。。IoTとか?
2017/04/15(土) 04:12:03.81ID:2Mj3RTtW
アセンブラはじめるならLinuxでやるといいよ
DOSと同じような感覚でアセンブラプログラミングができるから
こんな感じ
Linux でアセンブリプログラミング
http://www.mztn.org/lxasm/asm00.html
Linux で64bitアセンブリプログラミング
http://www.mztn.org/lxasm64/amd00.html
Linuxでのアセンブル方法はこんな感じ
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
ld -o hogehoge hogehoge.s
gccのでアセンブラ出力&アセンブル
gcc -S -o hogehoge.s hogehoge.c
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
gcc -o hogehoge hogehoge.o
DOSと同じような感覚でアセンブラプログラミングができるから
こんな感じ
Linux でアセンブリプログラミング
http://www.mztn.org/lxasm/asm00.html
Linux で64bitアセンブリプログラミング
http://www.mztn.org/lxasm64/amd00.html
Linuxでのアセンブル方法はこんな感じ
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
ld -o hogehoge hogehoge.s
gccのでアセンブラ出力&アセンブル
gcc -S -o hogehoge.s hogehoge.c
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
gcc -o hogehoge hogehoge.o
2017/04/15(土) 04:12:41.23ID:2Mj3RTtW
ちなみにx86_64上のLinuxで32bitのバイナリを作成したい場合はこう
x86_64のLinuxでのCの32bitのx86バイナリのコンパイル
gcc -m32 -O2 -o hogehoge hogehoge.c
x86_64のLinuxでの32bitのx86アセンブル
as --32 -a=hogehoge.lst -o hogehoge.o hogehoge.s
ld -melf_i386 -o hogehoge hogehoge.o
x86_64のLinuxでのgccので32bitアセンブラ出力&アセンブル
gcc -m32 -S -o hogehoge.s hogehoge.c
as --32 -a=hogehoge.lst -o hogehoge.o hogehoge.s
gcc -m32 -o hogehoge hogehoge.o
x86_64のLinuxでのCの32bitのx86バイナリのコンパイル
gcc -m32 -O2 -o hogehoge hogehoge.c
x86_64のLinuxでの32bitのx86アセンブル
as --32 -a=hogehoge.lst -o hogehoge.o hogehoge.s
ld -melf_i386 -o hogehoge hogehoge.o
x86_64のLinuxでのgccので32bitアセンブラ出力&アセンブル
gcc -m32 -S -o hogehoge.s hogehoge.c
as --32 -a=hogehoge.lst -o hogehoge.o hogehoge.s
gcc -m32 -o hogehoge hogehoge.o
2017/04/15(土) 04:13:21.76ID:2Mj3RTtW
nasmでのx86_64のLinuxでの32bitアセンブル
nasm -f elf hogehoge.s
ld -melf_i386 -o hogehoge hogehoge.o
nasmでのx86_64のLinuxでの64bitアセンブル
nasm -f elf64 $1.s
ld -o $1 $1.o
Ubuntuでのnasmのインストール方法
sudo apt-get install nasm
nasm -f elf hogehoge.s
ld -melf_i386 -o hogehoge hogehoge.o
nasmでのx86_64のLinuxでの64bitアセンブル
nasm -f elf64 $1.s
ld -o $1 $1.o
Ubuntuでのnasmのインストール方法
sudo apt-get install nasm
2017/04/15(土) 04:42:00.93ID:2Mj3RTtW
UbuntuだとQEMUを入れるだけでQEMU+binfmtの設定が自動せされるから
ライブラリへのリンクを貼るだけで他のCPUのバイナリをそのまま実行できるようになる
UbuntuだとARM、MIPS、PowerPCができる
64bitARMならこんな感じ
sudo apt-get install qemu
sudo apt-get install g++-aarch64-linux-gnu
sudo ln -s /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib
sudo ln -s /usr/aarch64-linux-gnu/lib /lib/aarch64-linux-gnu
32bitARMならこんな感じ
sudo apt-get install qemu
sudo apt-get install g++-arm-linux-gnueabihf
sudo ln -s /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 /lib
sudo ln -s /usr/arm-linux-gnueabihf/lib /lib/arm-linux-gnueabihf
Cのコンパイル方法はこんな感じ
aarch64-linux-gnu-gcc -O2 -o hogehoge hogehoge.c
arm-linux-gnueabihf-gcc -O2 -o hogehoge hogehoge.c
数学ライブラリを使う場合のCのコンパイル方法はこんな感じ
aarch64-linux-gnu-gcc -O2 -o hogehoge hogehoge.c -lm
(Ubuntuでは依存するライブラリを後ろに書く)
arm-linux-gnueabihf-gcc -O2 -o hogehoge hogehoge.c -lm
ライブラリへのリンクを貼るだけで他のCPUのバイナリをそのまま実行できるようになる
UbuntuだとARM、MIPS、PowerPCができる
64bitARMならこんな感じ
sudo apt-get install qemu
sudo apt-get install g++-aarch64-linux-gnu
sudo ln -s /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib
sudo ln -s /usr/aarch64-linux-gnu/lib /lib/aarch64-linux-gnu
32bitARMならこんな感じ
sudo apt-get install qemu
sudo apt-get install g++-arm-linux-gnueabihf
sudo ln -s /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 /lib
sudo ln -s /usr/arm-linux-gnueabihf/lib /lib/arm-linux-gnueabihf
Cのコンパイル方法はこんな感じ
aarch64-linux-gnu-gcc -O2 -o hogehoge hogehoge.c
arm-linux-gnueabihf-gcc -O2 -o hogehoge hogehoge.c
数学ライブラリを使う場合のCのコンパイル方法はこんな感じ
aarch64-linux-gnu-gcc -O2 -o hogehoge hogehoge.c -lm
(Ubuntuでは依存するライブラリを後ろに書く)
arm-linux-gnueabihf-gcc -O2 -o hogehoge hogehoge.c -lm
2017/04/15(土) 04:43:20.47ID:2Mj3RTtW
アセンブル方法はこんな感じ
aarch64-linux-gnu-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
aarch64-linux-gnu-ld -o hogehoge hogehoge.s
arm-linux-gnueabihf-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-ld -o hogehoge hogehoge.s
アセンブラソースの出力はこんな感じ
aarch64-linux-gnu-gcc -S -o hogehoge.s hogehoge.c
aarch64-linux-gnu-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
aarch64-linux-gnu-gcc -o hogehoge hogehoge.o
arm-linux-gnueabihf-gcc -S -o hogehoge.s hogehoge.c
arm-linux-gnueabihf-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-gcc -o hogehoge hogehoge.o
できたバイナリは普通に実行できる
./hogehoge
バイナリがどのアーキテクチャかはfileコマンドで確認できる
file hogehoge
aarch64-linux-gnu-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
aarch64-linux-gnu-ld -o hogehoge hogehoge.s
arm-linux-gnueabihf-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-ld -o hogehoge hogehoge.s
アセンブラソースの出力はこんな感じ
aarch64-linux-gnu-gcc -S -o hogehoge.s hogehoge.c
aarch64-linux-gnu-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
aarch64-linux-gnu-gcc -o hogehoge hogehoge.o
arm-linux-gnueabihf-gcc -S -o hogehoge.s hogehoge.c
arm-linux-gnueabihf-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-gcc -o hogehoge hogehoge.o
できたバイナリは普通に実行できる
./hogehoge
バイナリがどのアーキテクチャかはfileコマンドで確認できる
file hogehoge
2017/04/15(土) 04:44:00.98ID:2Mj3RTtW
32bitのARMでUbuntuのgnueabihfではデフォルトでThumb-2でコンパイルされる
ARM命令でコンパイルする場合はオプションを追加する
ARM命令の場合の例
-marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16
-marm -march=armv7-a -mfloat-abi=hard -mfpu=neon -ffast-math
実行例)
arm-linux-gnueabihf-gcc -O2 -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -o hogehoge hogehoge.c
arm-linux-gnueabihf-gcc -O2 -S -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -o hogehoge.s hogehoge.c
arm-linux-gnueabihf-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-gcc -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -o hogehoge hogehoge.o
参考)
Thumb-2命令の場合の例
-mthumb -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16
-mthumb -march=armv7-a -mfloat-abi=hard -mfpu=neon -ffast-math
ARM命令でコンパイルする場合はオプションを追加する
ARM命令の場合の例
-marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16
-marm -march=armv7-a -mfloat-abi=hard -mfpu=neon -ffast-math
実行例)
arm-linux-gnueabihf-gcc -O2 -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -o hogehoge hogehoge.c
arm-linux-gnueabihf-gcc -O2 -S -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -o hogehoge.s hogehoge.c
arm-linux-gnueabihf-as -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-gcc -marm -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -o hogehoge hogehoge.o
参考)
Thumb-2命令の場合の例
-mthumb -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16
-mthumb -march=armv7-a -mfloat-abi=hard -mfpu=neon -ffast-math
2017/04/15(土) 04:47:16.32ID:2Mj3RTtW
32bitARMアセンブラの参考URL
http://www.mztn.org/slasm/arm00.html
64bitbitARMアセンブラの参考URL
http://www.mztn.org/dragon/arm6400idx.html
http://www.mztn.org/slasm/arm00.html
64bitbitARMアセンブラの参考URL
http://www.mztn.org/dragon/arm6400idx.html
2017/04/15(土) 07:38:04.38ID:2Mj3RTtW
>>18の32bitARMのアセンブラのサイトの
http://www.mztn.org/slasm/arm04.html
1: ldrb r3, [r0, #+1]! @ r3=mem[r0++]
strb r3, [r1, #+1]! @ mem[r1++]=r3
でエラーが出ます
ここは
1: ldrb r3, [r0], #+1 @ r3=mem[r0++]
strb r3, [r1], #+1 @ mem[r1++]=r3
ですね
http://www.mztn.org/slasm/arm04.html
1: ldrb r3, [r0, #+1]! @ r3=mem[r0++]
strb r3, [r1, #+1]! @ mem[r1++]=r3
でエラーが出ます
ここは
1: ldrb r3, [r0], #+1 @ r3=mem[r0++]
strb r3, [r1], #+1 @ mem[r1++]=r3
ですね
2017/04/15(土) 08:02:58.82ID:2Mj3RTtW
補足
32bitARMでのシステムコールの呼び出しはEABIの方式で行ってください
.text
.align 2
.global _start
_start:
adr r1, msg @ address
mov r0, #1 @ stdout
mov r2, #13 @ length
mov r7, #4 @ sys_write
swi 0
mov r0, #0
mov r7, #1 @ sys_exit
swi 0
.align 2
msg:
.asciz "hello, world\n"
32bitARMでのシステムコールの呼び出しはEABIの方式で行ってください
.text
.align 2
.global _start
_start:
adr r1, msg @ address
mov r0, #1 @ stdout
mov r2, #13 @ length
mov r7, #4 @ sys_write
swi 0
mov r0, #0
mov r7, #1 @ sys_exit
swi 0
.align 2
msg:
.asciz "hello, world\n"
2017/04/15(土) 08:35:58.99ID:2Mj3RTtW
32bitARMでFPU命令を使う場合の例
arm-linux-gnueabihf-as -mfpu=vfpv2 -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-as -mfpu=vfpv3-d16 -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-as -mfpu=vfpv2 -a=hogehoge.lst -o hogehoge.o hogehoge.s
arm-linux-gnueabihf-as -mfpu=vfpv3-d16 -a=hogehoge.lst -o hogehoge.o hogehoge.s
2017/05/07(日) 22:56:59.24ID:8v4hzv7f
Intel AVX512とか32ビットモードや16ビットモードでマシン語記述できるの?
16ビットモード(MS−DOS6.2)で32ビット命令を実行できることは確認ずみ。
16ビットモード(MS−DOS6.2)で32ビット命令を実行できることは確認ずみ。
2017/05/08(月) 01:10:33.28ID:UxHus5NQ
どうやってマシン語生成するつもりか分からんが、マシン語は記述できるだろ。
2017/05/08(月) 01:56:11.92ID:+dlahwH0
>>22
REXプリフィックスは別の命令の再定義なので
REXプリフィックスは別の命令の再定義なので
25デフォルトの名無しさん
2017/05/09(火) 04:41:32.11ID:CfLPAbNS いまじゃ解析とか簡単になっとるからなぁ
小学生でもできるんじゃない?
小学生でもできるんじゃない?
2017/05/11(木) 21:51:54.08ID:+ulrHAZU
ねえねえ、Altivecって知ってる?
2017/05/13(土) 00:24:52.24ID:YNo+ODse
それ作ったチームはインテルでAVX512に関わったんだっけ
28デフォルトの名無しさん
2017/07/19(水) 15:57:14.47ID:4WYjcaP8 >>22
理屈の上ではアセンブラがそれらの命令をサポートしてれば可能。
ただ、今はアセンブラの方がMS-DOSサポートして無いだろうからクロス開発になりそう。
(動けば運が良かったって程度)
でもリアルモードでバイト数大きい64bit命令使うメリットは無い希ガス。
せめてプロテクトモードに移行してから64bit命令使った方が。。。
と言うか、Linuxのブートローダーからロングモード移行までの記事最近読んだけど、アセンブラから見たら多分16bit32bitじゃ無くてリアルモードかプロテクトモードかのが重要(使えるメモリの大きさが違う)な希ガス。
http://postd.cc/linux-bootstrap-1/
理屈の上ではアセンブラがそれらの命令をサポートしてれば可能。
ただ、今はアセンブラの方がMS-DOSサポートして無いだろうからクロス開発になりそう。
(動けば運が良かったって程度)
でもリアルモードでバイト数大きい64bit命令使うメリットは無い希ガス。
せめてプロテクトモードに移行してから64bit命令使った方が。。。
と言うか、Linuxのブートローダーからロングモード移行までの記事最近読んだけど、アセンブラから見たら多分16bit32bitじゃ無くてリアルモードかプロテクトモードかのが重要(使えるメモリの大きさが違う)な希ガス。
http://postd.cc/linux-bootstrap-1/
2017/10/19(木) 07:34:02.07ID:5IzztSYd
TLCS-900H2のDL命令の意味を教えてください
ソースを見る限りではCALLと同等のようですが
ソースを見る限りではCALLと同等のようですが
2017/12/20(水) 04:38:28.77ID:y3D7Mbgz
LibreOfficeのExcel互換アプリ calc では既にPythonでマクロが書ける
2017/12/20(水) 04:39:01.17ID:y3D7Mbgz
誤爆した。スマン
2017/12/22(金) 18:09:17.57ID:bOdX3AhV
excel最近使ってないわ
33デフォルトの名無しさん
2018/02/21(水) 13:16:23.71ID:VklNYIB8 初心者質問じゃないのだが、調べてもわからないので知ってる人がいたら教えて欲しい
Zynqを使ってハードウェアエミュレータを作ろうとしているんだが、
そのままだとアドレス0x40000000からしか自由に使えなくて困ってるんだけども、
Cortex-A9のMMUを設定するにはどうしたらいいんだろうか?
やりたいことはアドレス0x40000000から0x4FFFFFFFまでを0x00000000から0x0FFFFFFFにマッピングしたい
Zynqを使ってハードウェアエミュレータを作ろうとしているんだが、
そのままだとアドレス0x40000000からしか自由に使えなくて困ってるんだけども、
Cortex-A9のMMUを設定するにはどうしたらいいんだろうか?
やりたいことはアドレス0x40000000から0x4FFFFFFFまでを0x00000000から0x0FFFFFFFにマッピングしたい
2018/02/22(木) 03:37:57.63ID:hXyx6D5H
>>33
MMUについてどれだけ知っているのか分からないが
とりあえずLinuxのARMv7周りのコードを調べるのがよいと思われ
"linux arm source mmu"辺りをググッてみるとか
あとはARMのリファレンスマニュアル
http://infocenter.arm.com/help/index.jsp
から、「ARM アーキテクチャ」→「Reference Manuals」→「ARM アーキテクチャ リファレンス マニュアル ARMv7-A および ARMv7-R エディション」
のPDF、1267ページ以降を参照
大まかな手順としては
・ページテーブルを構築
・変換テーブルベースレジスタ(TTBR0、TTBR1)をセット
・変換テーブルベース制御レジスタ(TTBCR)をセット
・システム制御レジスタ(CP15 c1、SCTLR)レジスタのMMU有効化ビットをON
となると思われ
MMUについてどれだけ知っているのか分からないが
とりあえずLinuxのARMv7周りのコードを調べるのがよいと思われ
"linux arm source mmu"辺りをググッてみるとか
あとはARMのリファレンスマニュアル
http://infocenter.arm.com/help/index.jsp
から、「ARM アーキテクチャ」→「Reference Manuals」→「ARM アーキテクチャ リファレンス マニュアル ARMv7-A および ARMv7-R エディション」
のPDF、1267ページ以降を参照
大まかな手順としては
・ページテーブルを構築
・変換テーブルベースレジスタ(TTBR0、TTBR1)をセット
・変換テーブルベース制御レジスタ(TTBCR)をセット
・システム制御レジスタ(CP15 c1、SCTLR)レジスタのMMU有効化ビットをON
となると思われ
35デフォルトの名無しさん
2018/02/23(金) 00:45:14.45ID:ulmXMJQn2018/02/24(土) 13:07:22.87ID:tiS2olHY
>>34
armのドキュメント読みつつzynqでステップ実行しながらメモリの状態見てみたんだが、
以下の認識で合ってるだろうか?
・ページテーブルを構築
適当なメモリ領域にページテーブルを構築(要16kiBアラインメント)
(レジスタをいじって設定とかではなく例えば0x80000000番地に作っておく等)
・変換テーブルベースレジスタ(TTBR0、TTBR1)をセット
TTBR0はユーザー用、TTBR1はOS用
さっき用意したページテーブルの先頭アドレス(上位ビット)を渡す
下位ビットの方にその他の設定する
・システム制御レジスタ(CP15 c1、SCTLR)レジスタのMMU有効化ビットをON
SCTLRのBit0に1をセット
armのドキュメント読みつつzynqでステップ実行しながらメモリの状態見てみたんだが、
以下の認識で合ってるだろうか?
・ページテーブルを構築
適当なメモリ領域にページテーブルを構築(要16kiBアラインメント)
(レジスタをいじって設定とかではなく例えば0x80000000番地に作っておく等)
・変換テーブルベースレジスタ(TTBR0、TTBR1)をセット
TTBR0はユーザー用、TTBR1はOS用
さっき用意したページテーブルの先頭アドレス(上位ビット)を渡す
下位ビットの方にその他の設定する
・システム制御レジスタ(CP15 c1、SCTLR)レジスタのMMU有効化ビットをON
SCTLRのBit0に1をセット
2018/02/24(土) 18:39:17.01ID:B8xdCHC7
>>36
俺はARMはちゃんと触ってないので確実なことは言えないが
基本的にはそれで合っていると思う
ページテーブルとTTBRは物理アドレス(PA)で管理、ページテーブル内は仮想アドレス(VA)とPAの対応関係にアクセス保護ビット等
ページテーブルが2段以上(ページディレクトリ経由)になる場合はページディレクトリ内のデータの解釈が少し変わる
RISC系CPUはTLBミスヒットした時のテーブルウォークを自前で叩いてやらないといけない場合があったが、ARMv7ではCPUが自動でやる模様
あと微妙にキャッシュの管理とMMU周りの管理が絡み合っているようで、ここを俺は把握し切れていない
とにかく、Cortex-Aではコプロセッサ#15(CP15)がMMUなので、CP15の制御レジスタ周りをよく見ておいたほうがよいと思われ
俺はARMはちゃんと触ってないので確実なことは言えないが
基本的にはそれで合っていると思う
ページテーブルとTTBRは物理アドレス(PA)で管理、ページテーブル内は仮想アドレス(VA)とPAの対応関係にアクセス保護ビット等
ページテーブルが2段以上(ページディレクトリ経由)になる場合はページディレクトリ内のデータの解釈が少し変わる
RISC系CPUはTLBミスヒットした時のテーブルウォークを自前で叩いてやらないといけない場合があったが、ARMv7ではCPUが自動でやる模様
あと微妙にキャッシュの管理とMMU周りの管理が絡み合っているようで、ここを俺は把握し切れていない
とにかく、Cortex-Aではコプロセッサ#15(CP15)がMMUなので、CP15の制御レジスタ周りをよく見ておいたほうがよいと思われ
2018/02/25(日) 15:07:04.60ID:EC94jTzS
>>37
0x40000000の内容に0x00000000からアクセスできるようになった!
GBA(ARM7TDMI)のBIOSもちゃんと実行できてるっぽい
VRAM領域にアクセスしに行って止まってるが(;・∀・)
TLBのattributeの設定はとりあえず適当だが動いてるしよくわからんけど放置しよう・・・
0x40000000の内容に0x00000000からアクセスできるようになった!
GBA(ARM7TDMI)のBIOSもちゃんと実行できてるっぽい
VRAM領域にアクセスしに行って止まってるが(;・∀・)
TLBのattributeの設定はとりあえず適当だが動いてるしよくわからんけど放置しよう・・・
2018/02/25(日) 18:36:29.28ID:zm40u4G6
>>38
おめでとう!
おめでとう!
2018/02/26(月) 06:57:20.16ID:SxohJEGp
気楽にx86_64のアセンブラをやりたい人はこれを読むといいかもね
ただ、あまり詳しくは書かれてない
あくまで、初心者がx86_64アセンブラのとっかかりを掴むために読む本
CPUについての詳しい解説はあまり書かれてない(レジスタの解説程度)
x86_64のWindowsアセンブラ特有のスタックの使い方についても簡単に解説されてる
(x86_64のWindowsのアセンブラではスタック操作を自由にやってはいけない)
この本を読むとx86_64のアセンブラを簡単に試せるようになる
64ビットアセンブラ入門―64ビットCPUの基本構造もやさしく解説
https://www.amazon.co.jp/dp/4877833617/
ただ、あまり詳しくは書かれてない
あくまで、初心者がx86_64アセンブラのとっかかりを掴むために読む本
CPUについての詳しい解説はあまり書かれてない(レジスタの解説程度)
x86_64のWindowsアセンブラ特有のスタックの使い方についても簡単に解説されてる
(x86_64のWindowsのアセンブラではスタック操作を自由にやってはいけない)
この本を読むとx86_64のアセンブラを簡単に試せるようになる
64ビットアセンブラ入門―64ビットCPUの基本構造もやさしく解説
https://www.amazon.co.jp/dp/4877833617/
2018/02/26(月) 15:57:09.08ID:SxohJEGp
x86_64のWindowsのアセンブラで最初に嵌るのがスタック関係
ttp://herumi.in.coocan.jp/prog/x64.html
Windowsでのスタック
スタックは常に16byteアラインメントされています.
ただし関数呼び出し直後は戻りアドレス(8byte)がpushされているため, 8(mod 16)となっています.
関数内から別の関数を呼び出すときはアライメントを揃える必要があり,
引数4個のスタック分(32byte)を呼び出し元で確保する必要があります.
確保された領域は呼び出された側で自由に使えます.
Windowsでのスタックの扱い方はここのページを参照するといいかも
ttp://www.officedaytime.com/tips/asm64/caution.html
x64アセンブラ関数の書き方の注意【すごく要注意】
スタックが自由に使えない
32ビットまでのインラインアセンブラでは好き勝手にpush/popしたりして使えていたスタックが
x64では厳しい使用制限を受けることになりました。
具体的には以下のような制限です。
スタックポインタが動くような操作をしていいのは関数の最初と最後の部分だけ
(フレームポインタ(後述)を設定しない場合)。
その部分は「prolog」「epilog」と呼ばれ、やっていいことが決まっている。
prologが終わった時点でスタックポインタは16の倍数になっていなければならない
(中から他の関数を呼ばない場合はこの制限はない)。
ただし、push/popやその他の方法でRSPを動かさない、
何も呼び出さない、
壊してはいけないレジスタをセーブ(push/popに限らずいかなる方法でも)しない、
例外処理をしない、
のすべての条件を満たす関数は「leaf」(関数呼び出しツリーの枝の末端の葉っぱ、くらいの意味でしょうか)と呼ばれ、
この制限を受けません。
前ページのコーディング例にprolog/epilogがないのはそのためです。
-------以下、prolog/epilogの方法はページを参照-------
ttp://herumi.in.coocan.jp/prog/x64.html
Windowsでのスタック
スタックは常に16byteアラインメントされています.
ただし関数呼び出し直後は戻りアドレス(8byte)がpushされているため, 8(mod 16)となっています.
関数内から別の関数を呼び出すときはアライメントを揃える必要があり,
引数4個のスタック分(32byte)を呼び出し元で確保する必要があります.
確保された領域は呼び出された側で自由に使えます.
Windowsでのスタックの扱い方はここのページを参照するといいかも
ttp://www.officedaytime.com/tips/asm64/caution.html
x64アセンブラ関数の書き方の注意【すごく要注意】
スタックが自由に使えない
32ビットまでのインラインアセンブラでは好き勝手にpush/popしたりして使えていたスタックが
x64では厳しい使用制限を受けることになりました。
具体的には以下のような制限です。
スタックポインタが動くような操作をしていいのは関数の最初と最後の部分だけ
(フレームポインタ(後述)を設定しない場合)。
その部分は「prolog」「epilog」と呼ばれ、やっていいことが決まっている。
prologが終わった時点でスタックポインタは16の倍数になっていなければならない
(中から他の関数を呼ばない場合はこの制限はない)。
ただし、push/popやその他の方法でRSPを動かさない、
何も呼び出さない、
壊してはいけないレジスタをセーブ(push/popに限らずいかなる方法でも)しない、
例外処理をしない、
のすべての条件を満たす関数は「leaf」(関数呼び出しツリーの枝の末端の葉っぱ、くらいの意味でしょうか)と呼ばれ、
この制限を受けません。
前ページのコーディング例にprolog/epilogがないのはそのためです。
-------以下、prolog/epilogの方法はページを参照-------
42デフォルトの名無しさん
2018/02/28(水) 14:26:24.02ID:S610+cRR アライメントとアラインメントとか
用語もちゃんと揃えて欲しいな
用語もちゃんと揃えて欲しいな
2018/03/08(木) 20:28:48.99ID:uhDvi+9f
linuxでのx86_64のコンパイル&アセンブル
コンパイル
gcc -O2 -o hogehoge hogehoge.c
コンパイルでアセンブル出力&アセンブル&リンク
gcc -O2 -S -masm=intel -o hogehoge.s hogehoge.c
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
gcc -o hogehoge hogehoge.o
注:gccに-Sオプションを付けた場合に-masm=intelオプションを付けるとInteニーモニックのアセンブルリストが出力される
(デフォルトではAT&Tニーモニックで出力される)
アセンブル&リンク
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
ld -o hogehoge hogehoge.o
注:アセンブラソースに.intel_syntax noprefixを記述するとgasでIntelニーモニックを使えるようになる
(デフォルトではAT&Tニーモニック)
コンパイル
gcc -O2 -o hogehoge hogehoge.c
コンパイルでアセンブル出力&アセンブル&リンク
gcc -O2 -S -masm=intel -o hogehoge.s hogehoge.c
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
gcc -o hogehoge hogehoge.o
注:gccに-Sオプションを付けた場合に-masm=intelオプションを付けるとInteニーモニックのアセンブルリストが出力される
(デフォルトではAT&Tニーモニックで出力される)
アセンブル&リンク
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
ld -o hogehoge hogehoge.o
注:アセンブラソースに.intel_syntax noprefixを記述するとgasでIntelニーモニックを使えるようになる
(デフォルトではAT&Tニーモニック)
2018/03/08(木) 20:29:33.06ID:uhDvi+9f
例) Linuxアセンブラ版hello world
.intel_syntax noprefix
.text
.global _start
.align 4
_start:
mov rax, 1 # sys_write (1)
mov rdi, 1 # stdout (1)
movabs rsi, offset flat: msg # address(offsetを付けることによってアドレスをロードする)
# gasでは64bitイミディエイトや64bit絶対アドレス指定でのメモリからのロードを使う場合はmovabsを使う
mov rdx, offset flat: len # length(offsetを付けることによってアドレスをロードする)
syscall
mov rax, 60 # exit (60)
xor rdi, rdi # return 0
syscall
.data
.align 8
msg:
.asciz "hello, world\n"
.equ len, . - msg
.end
.intel_syntax noprefix
.text
.global _start
.align 4
_start:
mov rax, 1 # sys_write (1)
mov rdi, 1 # stdout (1)
movabs rsi, offset flat: msg # address(offsetを付けることによってアドレスをロードする)
# gasでは64bitイミディエイトや64bit絶対アドレス指定でのメモリからのロードを使う場合はmovabsを使う
mov rdx, offset flat: len # length(offsetを付けることによってアドレスをロードする)
syscall
mov rax, 60 # exit (60)
xor rdi, rdi # return 0
syscall
.data
.align 8
msg:
.asciz "hello, world\n"
.equ len, . - msg
.end
2018/03/08(木) 20:32:10.43ID:uhDvi+9f
64bitLinuxでの32bit x86のコンパイル&アセンブル
コンパイル
gcc -O2 -m32 -o hogehoge hogehoge.c
コンパイルでアセンブル出力&アセンブル&リンク
gcc -O2 -S -m32 -masm=intel -o hogehoge.s hogehoge.c
as -a=hogehoge.lst --32 -o hogehoge.o hogehoge.s
gcc -m32 -o hogehoge hogehoge.o
アセンブル&リンク
as -a=hogehoge.lst --32 -o hogehoge.o hogehoge.s
ld -melf_i386 -o hogehoge hogehoge.o
コンパイル
gcc -O2 -m32 -o hogehoge hogehoge.c
コンパイルでアセンブル出力&アセンブル&リンク
gcc -O2 -S -m32 -masm=intel -o hogehoge.s hogehoge.c
as -a=hogehoge.lst --32 -o hogehoge.o hogehoge.s
gcc -m32 -o hogehoge hogehoge.o
アセンブル&リンク
as -a=hogehoge.lst --32 -o hogehoge.o hogehoge.s
ld -melf_i386 -o hogehoge hogehoge.o
2018/03/08(木) 20:34:16.87ID:uhDvi+9f
例) Linuxアセンブラ版hello world(32bit)
.intel_syntax noprefix
.text
.global _start
.align 4
_start:
mov eax, 4 # sys_write (4)
mov ebx, 1 # stdout (1)
mov ecx, offset msg # address(offsetを付けることによってアドレスをロードする)
mov edx, offset len # length(offsetを付けることによってアドレスをロードする)
int 0x80
mov eax, 1 # exit (1)
xor ebx, ebx # return 0
int 0x80
.data
.align 4
msg:
.asciz "hello, world\n"
.equ len, . - msg
.end
.intel_syntax noprefix
.text
.global _start
.align 4
_start:
mov eax, 4 # sys_write (4)
mov ebx, 1 # stdout (1)
mov ecx, offset msg # address(offsetを付けることによってアドレスをロードする)
mov edx, offset len # length(offsetを付けることによってアドレスをロードする)
int 0x80
mov eax, 1 # exit (1)
xor ebx, ebx # return 0
int 0x80
.data
.align 4
msg:
.asciz "hello, world\n"
.equ len, . - msg
.end
47デフォルトの名無しさん
2018/03/10(土) 06:44:54.80ID:L0iyZELB あせんぶりゃー
あせんぶり
あせんぶる
あせんぶり
あせんぶる
2018/03/11(日) 17:22:40.99ID:lDE3fY11
x86_64のリファレンスマニュアル
インテルR エクステンデッド・メモリー 64 テクノロジー・ソフトウェア・デベロッパーズ・ガイド、第 1 巻
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL1_30083402_i.pdf
インテルR エクステンデッド・メモリー 64 テクノロジー・ソフトウェア・デベロッパーズ・ガイド、第 2 巻
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL2_30083502_i.pdf
インテルR エクステンデッド・メモリー 64 テクノロジー・ソフトウェア・デベロッパーズ・ガイド、第 1 巻
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL1_30083402_i.pdf
インテルR エクステンデッド・メモリー 64 テクノロジー・ソフトウェア・デベロッパーズ・ガイド、第 2 巻
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/EM64T_VOL2_30083502_i.pdf
2018/05/03(木) 11:01:18.80ID:0pg5Dj/G
8086にワード幅の相対ジャンプあるのに今頃気付いた…\(^O^)/…
orz
orz
2018/05/03(木) 11:36:54.78ID:83GzP0HZ
86には無くない?
386以降だった気がする
386以降だった気がする
2018/05/03(木) 11:38:07.04ID:83GzP0HZ
違った
相対ジャンプは、ほぼ全てが相対ジャンプだから、86からあるな
386からは、8bit限定じゃなくなったのは、条件ジャンブだ
相対ジャンプは、ほぼ全てが相対ジャンプだから、86からあるな
386からは、8bit限定じゃなくなったのは、条件ジャンブだ
2018/05/03(木) 12:21:57.39ID:0pg5Dj/G
うんまあそういう感じで多分勘違いしていた
というかワード幅のは絶対ジャンプといつのまにか思ってたらしい...(*ノノ)
というかワード幅のは絶対ジャンプといつのまにか思ってたらしい...(*ノノ)
53デフォルトの名無しさん
2018/05/03(木) 13:31:52.82ID:bkPu29QU Hugeモデルω
54デフォルトの名無しさん
2018/05/23(水) 19:33:19.00ID:Au5e7VGg 僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』
Z4DKB
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』
Z4DKB
2018/05/23(水) 19:44:16.48ID:q+YDJHjh
正規化HUGEとタイリングHUGE
2018/05/24(木) 10:55:44.30ID:cPlRxlDn
.
2018/06/13(水) 15:38:35.51ID:lSIEjw1a
その昔条件分岐のオフセットが8ビットを超えると勝手にnear分岐に展開してくれるアセンブラがあってだな
58デフォルトの名無しさん
2018/06/13(水) 15:56:44.91ID:mbrmHeFX で?
2018/06/13(水) 17:23:26.62ID:5n7sRExk
edas86覚えてる人いる?
60デフォルトの名無しさん
2018/07/04(水) 22:19:45.76ID:gFgZc5FG TDC
2018/07/05(木) 16:39:14.28ID:AeL6VB/V
TDC
2018/07/21(土) 07:03:04.58ID:HztBSU4B
オブジェクト指向のアセンブラアプリのお薦めを教えてください。
63デフォルトの名無しさん
2018/07/21(土) 10:03:59.76ID:JzufiDOi Julia
2018/07/31(火) 18:07:47.27ID:K5ZjI7P1
初心者なので意味が解らないんだけど、オブジェクト指向って考え方なんじゃないの?
2018/07/31(火) 23:36:25.25ID:M9aZq/V8
ところで、2つの32BIT レジスタの値を、64BITレジスタの上位32bit、下位32bit に
分けて入れる場合、shld を使えばいいのかな?
32BIT 時代の場合は、ebx <--- dx:ax としたい場合、
mov bx,dx
shl ebx,16
mov bx,ax
などとしたもんだけど、64BIT モードで、rbx <--- edx:eax としたい場合、
例えば、
shld rdx,rax,32
mov rbx,rbx
とするのかな。
分けて入れる場合、shld を使えばいいのかな?
32BIT 時代の場合は、ebx <--- dx:ax としたい場合、
mov bx,dx
shl ebx,16
mov bx,ax
などとしたもんだけど、64BIT モードで、rbx <--- edx:eax としたい場合、
例えば、
shld rdx,rax,32
mov rbx,rbx
とするのかな。
2018/07/31(火) 23:38:20.35ID:M9aZq/V8
あ、訂正させて。
多分、正しくは:
shl rax,32
shld rdx,rax,32
mov rbx,rbx
多分、正しくは:
shl rax,32
shld rdx,rax,32
mov rbx,rbx
2018/07/31(火) 23:39:52.06ID:M9aZq/V8
もしかして、mmx レジスタや xmm レジスタの、shuffle 命令なども使えたりする
のだろうか??
のだろうか??
2018/07/31(火) 23:44:49.05ID:M9aZq/V8
すまん。最訂正。
shl rax,32
shld rdx,rax,32
mov rbx,rdx
shl rax,32
shld rdx,rax,32
mov rbx,rdx
69デフォルトの名無しさん
2018/07/31(火) 23:51:35.80ID:PrQlt9wc >>68
もちつけ
もちつけ
2018/07/31(火) 23:53:48.39ID:Yh1Yhi2x
shl rdx, 16
mov ebx, eax
or rbx, rdx
mov ebx, eax
or rbx, rdx
2018/07/31(火) 23:55:11.65ID:Yh1Yhi2x
16じゃなくて32
2018/07/31(火) 23:58:34.01ID:M9aZq/V8
なるほど、つまり:
shl rdx, 32
mov ebx, eax
or rbx, rdx
と。OR を使うとは全く思いつかなかった。
shl rdx, 32
mov ebx, eax
or rbx, rdx
と。OR を使うとは全く思いつかなかった。
2018/08/01(水) 00:00:05.11ID:M1fpQAcB
考えてみれば、C言語ではいつも、シフトとOR使ってやってた・・・。
74デフォルトの名無しさん
2018/08/01(水) 00:02:01.85ID:s+zy6Um6 もちつけ
75デフォルトの名無しさん
2018/08/01(水) 00:17:55.42ID:M1fpQAcB 【まとめ】
64BIT モードでは、mov 命令などの destination が、32BITレジスタの場合、
原則的に、対応する64BITレジスタの上位32BITがゼロクリアされてしまうの
で注意が必要。蛇足だが、destinationが16BITレジスタや8BITレジスタの
場合は、対応する64BITレジスタの残りの上位ビットは完全に保持される。
この結果、2つの同じビット数のレジスタを2倍のビット数のレジスタの上位、下位
に代入したい場合、
32BIT Legacy Mode で、ebx <--- dx:ax としたい場合、
mov bx,dx
shl ebx,16
mov bx,ax ;ebx(64BITモードだと、rbx) の上位16ビット(上位48BIT)は、
;直前のまま変化しない。
で良かったが、
64BIT モードで、rbx <--- edx:eax としたい場合、
shl rdx, 32 ; 左シフトの結果、rdx の下位32BIT は、0になる。
mov ebx, eax ; rbx の上位32BIT は(勝手に)0クリアされる。
or rbx, rdx
や、
shl rax,32 ; 左シフトの結果、rax の上位32BITに元の eaxが入る事になる。
shld rdx,rax,32 ; rdx : rax をひとまとめにして 32BIT分、左シフト。
mov rbx,rdx
などとする必要がある。
64BIT モードでは、mov 命令などの destination が、32BITレジスタの場合、
原則的に、対応する64BITレジスタの上位32BITがゼロクリアされてしまうの
で注意が必要。蛇足だが、destinationが16BITレジスタや8BITレジスタの
場合は、対応する64BITレジスタの残りの上位ビットは完全に保持される。
この結果、2つの同じビット数のレジスタを2倍のビット数のレジスタの上位、下位
に代入したい場合、
32BIT Legacy Mode で、ebx <--- dx:ax としたい場合、
mov bx,dx
shl ebx,16
mov bx,ax ;ebx(64BITモードだと、rbx) の上位16ビット(上位48BIT)は、
;直前のまま変化しない。
で良かったが、
64BIT モードで、rbx <--- edx:eax としたい場合、
shl rdx, 32 ; 左シフトの結果、rdx の下位32BIT は、0になる。
mov ebx, eax ; rbx の上位32BIT は(勝手に)0クリアされる。
or rbx, rdx
や、
shl rax,32 ; 左シフトの結果、rax の上位32BITに元の eaxが入る事になる。
shld rdx,rax,32 ; rdx : rax をひとまとめにして 32BIT分、左シフト。
mov rbx,rdx
などとする必要がある。
2018/08/01(水) 00:48:03.95ID:hfBYO5dB
64bitレジスタの上位が0になるのは無駄な依存関係を無くすため
32bitレジスタの部分書き換えは大きなペナルティが発生するので注意
32bitレジスタの部分書き換えは大きなペナルティが発生するので注意
2018/08/01(水) 00:52:48.93ID:hfBYO5dB
アセンブラで高速なコードを書くなら
インテルの最適化マニュアルを一通り読むことを勧める
IACAも非常に便利
インテルの最適化マニュアルを一通り読むことを勧める
IACAも非常に便利
2018/08/01(水) 20:01:51.01ID:UPXl5ngF
アセンブラは普通に書いただけでもCに比べてバイナリも非常に小さいし高速に動いてくれるよね
2018/08/01(水) 23:09:30.00ID:iFKJPY0w
ペナルティを避けるため、普通は同じレジスタでも別のでもいいから、movzx使って上位ビットが0だって明示してから使うべき
2018/08/01(水) 23:17:32.46ID:iFKJPY0w
今回の64ビットバージョンのrbx <--- edx:eax としたい場合は関係なかったけど、
mov bx,dxをやった後にebxやrbxを参照するとペナルティが発生するのは32ビットでも一緒だけどね
mov bx,dxをやった後にebxやrbxを参照するとペナルティが発生するのは32ビットでも一緒だけどね
2018/08/02(木) 20:11:37.64ID:Hff70ZxX
2018/08/02(木) 20:19:01.70ID:1EegAYN5
それ
2018/08/02(木) 21:46:38.87ID:Hff70ZxX
IACAってなんかすごい
2018/08/02(木) 23:06:24.79ID:vIaAZbox
>>79
確か、64BIT モードだと、そもそも、movzx reg64,reg32 に相当する専用命令が
存在せず、その代わりに、単なる mov reg32,reg32 を使う想定になっているはず。
なぜなら、後者でも上位32BITが0になるから。
一方、movsx reg64,reg32 については、新しい新命令として、movsxd なる
ものが導入されている。なぜなら、movsx の第二オペランドは、32BIT時代
から、8BIT か、16BIT レジスタしか採りえないから。命令自体で
第二オペランドのビット数が固定されていて、第二オペランドが
8BIT と 16BIT で別々の opcode になっていて、0x66 prefix でデータサイズ
を変えた場合は、第一オペランドのサイズが変わるだけ、という仕様だった
から。つまり、64BITモードでも、第二オペランドのBIT数は、
opcode 自体で固定されてしまっているので、REX.W や 0x66 prefix では
第二オペランドのBIT数の変更はされない、というのが素直な解釈だったから。
確か、64BIT モードだと、そもそも、movzx reg64,reg32 に相当する専用命令が
存在せず、その代わりに、単なる mov reg32,reg32 を使う想定になっているはず。
なぜなら、後者でも上位32BITが0になるから。
一方、movsx reg64,reg32 については、新しい新命令として、movsxd なる
ものが導入されている。なぜなら、movsx の第二オペランドは、32BIT時代
から、8BIT か、16BIT レジスタしか採りえないから。命令自体で
第二オペランドのビット数が固定されていて、第二オペランドが
8BIT と 16BIT で別々の opcode になっていて、0x66 prefix でデータサイズ
を変えた場合は、第一オペランドのサイズが変わるだけ、という仕様だった
から。つまり、64BITモードでも、第二オペランドのBIT数は、
opcode 自体で固定されてしまっているので、REX.W や 0x66 prefix では
第二オペランドのBIT数の変更はされない、というのが素直な解釈だったから。
2018/08/11(土) 19:53:27.03ID:Pi7uIeu1
[test3.asm]
.data
my_mojiretu db 'somothing', 0 ;1
.code
mov rax,offset my_mojiretu ;2
xor rbx,rbx
mov al,my_mojiretu[rbx] ;3
-------------------------------------------------------------------
2 は、大丈夫なのに、3 だと、以下のようなエラーになる。なぜ?
test3.obj に「絶対アドレス」の relocation 情報が入ることにはなるハズなんだけど。
J:\Develop\C\masm64_s\masm64>d:\ml64\bin\ml64.exe /Fl test3.asm /link /libpath:"
C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64" /subsystem:windows /def
aultlib:kernel32.lib /defaultlib:user32.lib /entry:main
Microsoft (R) Macro Assembler (x64) Version 9.00.30729.207
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: test3.asm
Microsoft (R) Incremental Linker Version 9.00.30729.207
Copyright (C) Microsoft Corporation. All rights reserved.
/OUT:test3.exe
test3.obj
"/libpath:C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64"
/subsystem:windows
/defaultlib:kernel32.lib
/defaultlib:user32.lib
/entry:main
test3.obj : error LNK2017: 'ADDR32' relocation to 'my_title' invalid without /LA
RGEADDRESSAWARE:NO
LINK : fatal error LNK1165: link failed because of fixup errors
.data
my_mojiretu db 'somothing', 0 ;1
.code
mov rax,offset my_mojiretu ;2
xor rbx,rbx
mov al,my_mojiretu[rbx] ;3
-------------------------------------------------------------------
2 は、大丈夫なのに、3 だと、以下のようなエラーになる。なぜ?
test3.obj に「絶対アドレス」の relocation 情報が入ることにはなるハズなんだけど。
J:\Develop\C\masm64_s\masm64>d:\ml64\bin\ml64.exe /Fl test3.asm /link /libpath:"
C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64" /subsystem:windows /def
aultlib:kernel32.lib /defaultlib:user32.lib /entry:main
Microsoft (R) Macro Assembler (x64) Version 9.00.30729.207
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: test3.asm
Microsoft (R) Incremental Linker Version 9.00.30729.207
Copyright (C) Microsoft Corporation. All rights reserved.
/OUT:test3.exe
test3.obj
"/libpath:C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x64"
/subsystem:windows
/defaultlib:kernel32.lib
/defaultlib:user32.lib
/entry:main
test3.obj : error LNK2017: 'ADDR32' relocation to 'my_title' invalid without /LA
RGEADDRESSAWARE:NO
LINK : fatal error LNK1165: link failed because of fixup errors
2018/08/11(土) 19:55:58.66ID:Pi7uIeu1
エラーでは、my_title になってるけど、5ch に登校する際に、
ソースを my_mojiretu に変えただけなので、同じと思って。
あと、somothing は、something の typo。
ソースを my_mojiretu に変えただけなので、同じと思って。
あと、somothing は、something の typo。
2018/08/11(土) 20:05:28.32ID:Pi7uIeu1
あー。例外的に2の部分の、
mov reg,imm
は、imm に 64BIT 即値が入れられるけど、3の部分では、
ModRMの間接参照の
[ebx + disp]
を使ってるけど、この形では、dispに32BIT までしか入れられないからだな。。。
なるほど。つまり、
mov al,my_mojioretu[ebx]
は、
mov al,[ebx + disp64]
としたくても、AMD64 ではそのようなメモリオペランドが使えないので、
mov al,[ebx + disp32]
にしかアセンブルできないと。
だから、絶対アドレスが、32BIT を超えるような値になった場合にはどうしようも
ないと。
mov reg,imm
は、imm に 64BIT 即値が入れられるけど、3の部分では、
ModRMの間接参照の
[ebx + disp]
を使ってるけど、この形では、dispに32BIT までしか入れられないからだな。。。
なるほど。つまり、
mov al,my_mojioretu[ebx]
は、
mov al,[ebx + disp64]
としたくても、AMD64 ではそのようなメモリオペランドが使えないので、
mov al,[ebx + disp32]
にしかアセンブルできないと。
だから、絶対アドレスが、32BIT を超えるような値になった場合にはどうしようも
ないと。
2018/08/11(土) 20:08:54.58ID:XlVyBwpc
ちょっと勉強になった
64bitでasm触ることなくなったもんなー
64bitでasm触ることなくなったもんなー
2018/08/11(土) 22:13:23.67ID:QecvtyFY
2018/08/12(日) 06:39:04.85ID:kb51JNcZ
2018/08/12(日) 06:49:59.09ID:kb51JNcZ
AMD64 では、ModRM を使った MemoryOperand の [reg64 + disp] のような形式の場合、
disp の BIT 数が、最大でも、
[reg64 + disp32]
のように 32BIT までが限界で、64BIT の disp64 は存在していない。
imm も「一般的には」、imm32 までで、imm64 は使えない。
ところが、mov reg,imm に関しては、例外的に
mov reg64, imm64
という命令が存在している。また、似た話として、
ModRM を使わない MemoryOperand では、disp64 のようなものが例外的に
存在していて、
mov reg,[disp64]
というものが存在している。ただし、意味的には、[disp64] ではなく、[moffset64]
のような意味合いで、
mov reg,[moffset64] や
mov reg,moffset64
と書かれることがある。この場合、[] が付いてなくても意味は同じ(混乱注意)。
ちなみに、mem64 は、データサイズが 64BIT という意味なので、
qword ptr [xxxx]
の意味になるので、また違う。
つまり、レジスタに入れてアクセスできるアドレスは64BITなのに、固定アドレスを入れてアクセス
できるメモリは、32BIT に制限されやすい、ということ。ただし、上記のような例外が用意されている
ので、絶対に32BITを超えた固定アドレスのメモリをアクセスできないというわけではない。
disp の BIT 数が、最大でも、
[reg64 + disp32]
のように 32BIT までが限界で、64BIT の disp64 は存在していない。
imm も「一般的には」、imm32 までで、imm64 は使えない。
ところが、mov reg,imm に関しては、例外的に
mov reg64, imm64
という命令が存在している。また、似た話として、
ModRM を使わない MemoryOperand では、disp64 のようなものが例外的に
存在していて、
mov reg,[disp64]
というものが存在している。ただし、意味的には、[disp64] ではなく、[moffset64]
のような意味合いで、
mov reg,[moffset64] や
mov reg,moffset64
と書かれることがある。この場合、[] が付いてなくても意味は同じ(混乱注意)。
ちなみに、mem64 は、データサイズが 64BIT という意味なので、
qword ptr [xxxx]
の意味になるので、また違う。
つまり、レジスタに入れてアクセスできるアドレスは64BITなのに、固定アドレスを入れてアクセス
できるメモリは、32BIT に制限されやすい、ということ。ただし、上記のような例外が用意されている
ので、絶対に32BITを超えた固定アドレスのメモリをアクセスできないというわけではない。
2018/08/12(日) 06:59:38.95ID:kb51JNcZ
ちなみに、
.data
ラベル名 db 'xxxx',0 ;1
.code
lea ebx,ラベル名 ;2
のような場合、一見、2の第二オペランドは、ModRM に encode されるので、
lea ebx,[disp32]
になってしまうから、この場合も、32BIT の限界に遭遇してしまうのではないかと
思ってしまうかもしれない。ところが、実際には、
lea ebx,[rip + rel_addr32]
のように命令ポインタの rip 相対のアドレスとして、encode されるので、また、事情が
違ってくる。結論的には、この場合は、ラベル名がリンクに指定した obj の中にある
限りにおいては、32BIT の限界を特に気にすることは無い。
.data
ラベル名 db 'xxxx',0 ;1
.code
lea ebx,ラベル名 ;2
のような場合、一見、2の第二オペランドは、ModRM に encode されるので、
lea ebx,[disp32]
になってしまうから、この場合も、32BIT の限界に遭遇してしまうのではないかと
思ってしまうかもしれない。ところが、実際には、
lea ebx,[rip + rel_addr32]
のように命令ポインタの rip 相対のアドレスとして、encode されるので、また、事情が
違ってくる。結論的には、この場合は、ラベル名がリンクに指定した obj の中にある
限りにおいては、32BIT の限界を特に気にすることは無い。
2018/08/12(日) 07:04:02.85ID:kb51JNcZ
>>92
間違った。 ebx ではなく、rbx だった:
lea rbx,ラベル名 ;2
lea rbx,[disp32]
lea rbx,[rip + rel_addr32]
間違った。 ebx ではなく、rbx だった:
lea rbx,ラベル名 ;2
lea rbx,[disp32]
lea rbx,[rip + rel_addr32]
2018/08/16(木) 12:39:22.96ID:ZqqdGQwm
>>41
実は、以下のようにしておくだけで、SEH例外のサポートも含めて、
ほぼ、push, pop は自由に出来るようになるらしい。
1. 関数の最初と最後を以下のように書く :
push rbp
mov rbp, rsp
・・・
pop rbp
ret
2. rbp を frame pointer に使っているということを、関数の prolog に書く。
【「ほぼ」 の例外】
call 関数名などの関数コールの直前では、rsp を16バイトアラインしてある
必要があること。それさえ気をつけていれば、push, pop は自由に行える。
【16倍とスタックアラインについて】
push rbp のおかげで、return address の 8 バイトと合わせて、直後からは、
上手く勝手に rsp が 16 バイトにアラインされた状態になってくれる。
だから、余り難しい事を考える必要は無い。
実は、以下のようにしておくだけで、SEH例外のサポートも含めて、
ほぼ、push, pop は自由に出来るようになるらしい。
1. 関数の最初と最後を以下のように書く :
push rbp
mov rbp, rsp
・・・
pop rbp
ret
2. rbp を frame pointer に使っているということを、関数の prolog に書く。
【「ほぼ」 の例外】
call 関数名などの関数コールの直前では、rsp を16バイトアラインしてある
必要があること。それさえ気をつけていれば、push, pop は自由に行える。
【16倍とスタックアラインについて】
push rbp のおかげで、return address の 8 バイトと合わせて、直後からは、
上手く勝手に rsp が 16 バイトにアラインされた状態になってくれる。
だから、余り難しい事を考える必要は無い。
2018/08/16(木) 13:12:50.69ID:ZqqdGQwm
frame pointer(rbp) を使わない場合は、関数の通常部分では、rsp を最初から最後まで
固定しなくては、構造化例外を処理出来なくなる。
なので、rsp が変化する事になる push, pop が使えなくなる。
(なお、人間にとっては便利でも、コンパイラにとっては、元々 push, pop は使いにくい
命令であった。)
x86、x64 アーキテクチャでは、mov reg, reg/mem のような事は出来ても、
mov mem, mem は出来ない。ところが、この、push, pop についてはそれが
出来てしまう数少ない例外。
例えば、
push qword ptr [ebp + disp1] ;1
や
push qword ptr [esp + disp1] ;2
で、ローカルの auto 変数をスタックに保存する事が出来る。ところが、
mov qwrod ptr [esp + disp1], qword ptr [esp + disp2] ;3
とは出来ない。だから、push 命令を使うと、実はパフォーマンスが向上する可能性も
秘めてはいるかも知れない。ただし、これも、レジスタの個数が十分沢山ある
近年では、必ずしもそうとも言えないかもしれない。レジスタの個数が不足して
スタックに保存したくなった場合、
mov [esp + disp1], reg ;4
と書けばいいわけであって、3 のように書く必要性は、近年では下がっているようだから。
固定しなくては、構造化例外を処理出来なくなる。
なので、rsp が変化する事になる push, pop が使えなくなる。
(なお、人間にとっては便利でも、コンパイラにとっては、元々 push, pop は使いにくい
命令であった。)
x86、x64 アーキテクチャでは、mov reg, reg/mem のような事は出来ても、
mov mem, mem は出来ない。ところが、この、push, pop についてはそれが
出来てしまう数少ない例外。
例えば、
push qword ptr [ebp + disp1] ;1
や
push qword ptr [esp + disp1] ;2
で、ローカルの auto 変数をスタックに保存する事が出来る。ところが、
mov qwrod ptr [esp + disp1], qword ptr [esp + disp2] ;3
とは出来ない。だから、push 命令を使うと、実はパフォーマンスが向上する可能性も
秘めてはいるかも知れない。ただし、これも、レジスタの個数が十分沢山ある
近年では、必ずしもそうとも言えないかもしれない。レジスタの個数が不足して
スタックに保存したくなった場合、
mov [esp + disp1], reg ;4
と書けばいいわけであって、3 のように書く必要性は、近年では下がっているようだから。
2018/08/16(木) 13:27:50.54ID:ZqqdGQwm
>>95
誤:esp, ebp
正:rsp, rbp
【なぜ、3の必要性が少ないかについて】
3のようにしなくても、そもそも、3の第二オペランドの値は、メモリ上において
あるのだから、レジスタが不足しても値が消えてしまう事はない。だから、
保存の必要も無い。
レジスタが不足した場合に保存する必要があるのは、必ずレジスタの値。
だから、mov [rsp + disp], reg の形式で十分保存できてしまう。
誤:esp, ebp
正:rsp, rbp
【なぜ、3の必要性が少ないかについて】
3のようにしなくても、そもそも、3の第二オペランドの値は、メモリ上において
あるのだから、レジスタが不足しても値が消えてしまう事はない。だから、
保存の必要も無い。
レジスタが不足した場合に保存する必要があるのは、必ずレジスタの値。
だから、mov [rsp + disp], reg の形式で十分保存できてしまう。
2018/08/16(木) 15:37:56.45ID:y9SUHRBN
2018/08/16(木) 21:00:56.95ID:aOzS/OcU
内部的にロード、ストアは別命令
アセンブラの命令数とかあまり関係ない
アセンブラの命令数とかあまり関係ない
2018/08/18(土) 06:32:40.93ID:v9RxAPQU
100デフォルトの名無しさん
2018/08/18(土) 06:35:45.68ID:v9RxAPQU push、popはコードサイズに制限のある、プロローグ、エピローグ部分で使うことはあるけど、
あまり必要性はなくなったよ。
あまり必要性はなくなったよ。
101デフォルトの名無しさん
2018/08/18(土) 07:05:31.99ID:v9RxAPQU push、popみたいに複数のμOPになる命令は利用可能なデコーダーも制限されるので
他の命令のデコードも阻害しやすい。
演算命令のメモリオペランドみたいに、フュージョンされて簡単デコーダーで発行できるようになったのもあるけど。
他の命令のデコードも阻害しやすい。
演算命令のメモリオペランドみたいに、フュージョンされて簡単デコーダーで発行できるようになったのもあるけど。
102デフォルトの名無しさん
2018/08/18(土) 08:53:46.48ID:LWSvYoUk103デフォルトの名無しさん
2018/08/18(土) 09:10:13.08ID:LWSvYoUk104デフォルトの名無しさん
2018/08/18(土) 14:23:17.32ID:LlnBri0A >>103
それ、可能と言えば可能だけど、64bit化のメリットのかなりの部分が消えてしまうし、
DLLでも制限なく使えるんだっけ?
と思って調べたらやっぱ問題あるよなあ。
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
それ、可能と言えば可能だけど、64bit化のメリットのかなりの部分が消えてしまうし、
DLLでも制限なく使えるんだっけ?
と思って調べたらやっぱ問題あるよなあ。
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
105デフォルトの名無しさん
2018/08/18(土) 19:54:44.26ID:D84MOd5V >>103
mov cl, hogehoge
これでアセンブルして、dumpbin /relocations test01.obj
これで見ると
hogehogeがREL32になる(PC相対の32bitオフセット)
ラベルの種類としてRIP相対のREL32はあるけど
通常のレジスタに32bit相対のラベルの種類がないのでは?
だからエラーになると
mov cl, hogehoge
これでアセンブルして、dumpbin /relocations test01.obj
これで見ると
hogehogeがREL32になる(PC相対の32bitオフセット)
ラベルの種類としてRIP相対のREL32はあるけど
通常のレジスタに32bit相対のラベルの種類がないのでは?
だからエラーになると
106デフォルトの名無しさん
2018/08/18(土) 21:13:26.29ID:D84MOd5V 簡単なWindowsのアプリを作ってWinMainのアドレスを表示すると
0x000000003fdf1770
俺の環境ではこんな値が出た
これってアドレスとしては1GBくらいの位置
下位32bitの絶対アドレスで指定すると符号付と解釈した場合に
残り1GBの範囲しかアクセスできない
だから、64bitのWindowsや/3GBスイッチを指定した32bitWindowsでは
下位32bitの絶対アドレスで指定するなとマイクロソフトは決めたのでは?
RIP相対なら開始アドレスに関係なくRIPの相対値なので
プログラムがロードされた位置に関わらず2GBまでアクセスできる
0x000000003fdf1770
俺の環境ではこんな値が出た
これってアドレスとしては1GBくらいの位置
下位32bitの絶対アドレスで指定すると符号付と解釈した場合に
残り1GBの範囲しかアクセスできない
だから、64bitのWindowsや/3GBスイッチを指定した32bitWindowsでは
下位32bitの絶対アドレスで指定するなとマイクロソフトは決めたのでは?
RIP相対なら開始アドレスに関係なくRIPの相対値なので
プログラムがロードされた位置に関わらず2GBまでアクセスできる
107デフォルトの名無しさん
2018/08/18(土) 21:29:59.45ID:D84MOd5V 同じようなプログラムを32bitで作ってコンパイルしたらWinMainの開始アドレスは
0x013215a0
アドレスとしては19MBくらいの位置
64bitアプリは32bitアプリよりもずっと高位のアドレスにロードされるんだろうね
だから64bitアプリでは下位32bitでの絶対アドレス指定は禁止してるのかも
0x013215a0
アドレスとしては19MBくらいの位置
64bitアプリは32bitアプリよりもずっと高位のアドレスにロードされるんだろうね
だから64bitアプリでは下位32bitでの絶対アドレス指定は禁止してるのかも
108デフォルトの名無しさん
2018/08/19(日) 12:41:20.07ID:plhuPGbS 論理的に高位か下位かはどうでもよくね?
109デフォルトの名無しさん
2018/08/19(日) 16:59:22.46ID:XvleiWNb110デフォルトの名無しさん
2018/08/19(日) 17:05:58.03ID:XvleiWNb だからこそ
>>85の
mov al,my_mojiretu[rbx] ;3
のようなコードを書くとリンカがエラーを吐くようになってるんだろうね
下位32bitの絶対アドレスで指定するなと
>>85の
mov al,my_mojiretu[rbx] ;3
のようなコードを書くとリンカがエラーを吐くようになってるんだろうね
下位32bitの絶対アドレスで指定するなと
111デフォルトの名無しさん
2018/08/19(日) 17:21:35.92ID:XvleiWNb ほとんどのCPUでは64bitのアドレスを直接指定する方法は限定されてて、実行速度も遅くなる
だからWindowsやLinuxでは64bitでもデフォルトではスタティックに割り当てられたシンボルは
だいたい32bitの値として扱ってる
(Linuxではコンパイラのオプションでメモリモデルを指定できて
スタティックなシンボルを64bitの値として扱うこともできる)
64bit Windowsの場合、かなり高位のアドレスにロードされるようだから
RIP相対の32bitの値として扱ってるのだろう
ちなみにこれはスタティックに割り当てられたデータだけで動的に割り当てられたデータは
64bitのポインタ値で扱われるのでユーザプログラムが扱える全仮想メモリ領域に配置できる
だからWindowsやLinuxでは64bitでもデフォルトではスタティックに割り当てられたシンボルは
だいたい32bitの値として扱ってる
(Linuxではコンパイラのオプションでメモリモデルを指定できて
スタティックなシンボルを64bitの値として扱うこともできる)
64bit Windowsの場合、かなり高位のアドレスにロードされるようだから
RIP相対の32bitの値として扱ってるのだろう
ちなみにこれはスタティックに割り当てられたデータだけで動的に割り当てられたデータは
64bitのポインタ値で扱われるのでユーザプログラムが扱える全仮想メモリ領域に配置できる
112デフォルトの名無しさん
2018/08/19(日) 17:30:58.64ID:XvleiWNb 64bitARMの場合、Linuxではスタティックなシンボル値読み込む場合
adrp x0, :pg_hi21:hogehoge
add x0, x0, :lo12:hogehoge
これで読み込む
これで33bitのページ単位でPC相対のアドレスを読み込める
つまり64bitのARMではスタティックなシンボル値は33bitのPC相対アドレスとして扱ってる
(相対なのはページ単位なので下位12bitは動かせない、下位12bitは絶対アドレス値を足してるので)
adrp x0, :pg_hi21:hogehoge
add x0, x0, :lo12:hogehoge
これで読み込む
これで33bitのページ単位でPC相対のアドレスを読み込める
つまり64bitのARMではスタティックなシンボル値は33bitのPC相対アドレスとして扱ってる
(相対なのはページ単位なので下位12bitは動かせない、下位12bitは絶対アドレス値を足してるので)
113デフォルトの名無しさん
2018/08/19(日) 17:34:00.29ID:XvleiWNb 64bitのARMのadrp命令と同等の命令はRISC-Vや最近発表されたnanoMIPSなどでも採用されてる
RISC-VやnanoMIPSは33bitではなく32bitだが
RISC-VやnanoMIPSは33bitではなく32bitだが
114デフォルトの名無しさん
2018/08/19(日) 17:41:09.62ID:XvleiWNb スタティックなシンボル値の制約はアセンブラではなくあくまでコンパイラの仕様だが
(コンパイラ側でシンボルを扱う場合にあえて下位32bitしか読み込まない仕様にしてる)
最近のアセンブラプログラミングでは高級言語とリンクすることが多いので必須な知識
(コンパイラ側でシンボルを扱う場合にあえて下位32bitしか読み込まない仕様にしてる)
最近のアセンブラプログラミングでは高級言語とリンクすることが多いので必須な知識
115デフォルトの名無しさん
2018/08/19(日) 19:20:24.59ID:r48xSuow >>111
> ちなみにこれはスタティックに割り当てられたデータだけで動的に割り当てられたデータは
> 64bitのポインタ値で扱われるのでユーザプログラムが扱える全仮想メモリ領域に配置できる
> ほとんどのCPUでは64bitのアドレスを直接指定する方法は限定されてて、実行速度も遅くなる
つまりこういうこと?
・動的に割り当てられたデータは64bitでアクセスできるけど実行速度が遅くなる
・静的に割り当てられたデータは32bitでアクセスするように制限されてるけど実行速度は速い。
・ただしLinuxの場合、メモリモデルを指定して再コンパイルすればこの制限はなくなる
> ちなみにこれはスタティックに割り当てられたデータだけで動的に割り当てられたデータは
> 64bitのポインタ値で扱われるのでユーザプログラムが扱える全仮想メモリ領域に配置できる
> ほとんどのCPUでは64bitのアドレスを直接指定する方法は限定されてて、実行速度も遅くなる
つまりこういうこと?
・動的に割り当てられたデータは64bitでアクセスできるけど実行速度が遅くなる
・静的に割り当てられたデータは32bitでアクセスするように制限されてるけど実行速度は速い。
・ただしLinuxの場合、メモリモデルを指定して再コンパイルすればこの制限はなくなる
116デフォルトの名無しさん
2018/08/19(日) 20:02:42.41ID:XvleiWNb >>115
>・動的に割り当てられたデータは64bitでアクセスできるけど実行速度が遅くなる
そもそも動的なデータは64bitのポインタで管理されるので最初から全アドレスにアクセスできる
>・静的に割り当てられたデータは32bitでアクセスするように制限されてるけど実行速度は速い。
違う、あくまでシンボルを32bitのアドレスとして読み込んでるだけでデータサイズは関係ない
x86_64でも64bitのアドレスを指定して読み込む命令は限られてるし、
実行速度の面でも効率が悪いのでRIP相対で32bit分だけを使ってる
たとえば、
mov rcx, data01
とした場合、data01の部分はRIP相対の32bitアドレスになる、読み込まれるデータは64bitの値
RISC CPUだとアドレスを読み込んでからデータに読み書きするという2段階になるので
たとえば、64bitのARMだと
adrp x0, :pg_hi21:data01
add x0, x0, :lo12:data01
ldr x0, [x0]
と下位33bitでPC相対アドレスとしてシンボルが読み込まれる
RISC-Vの絶対アドレスだと
lui a0, a0, data01
addi a0, a0, data01
ld a0, (a0)
PC相対だと
1: auipc a0, %pcrel_hi(data01)
addi a0, a0, %pcrel_lo(1b)
ld a0, (a0)
こうなる
(%pcrel_lo()では対応するpcrel_hi()のラベルを指定)
>・動的に割り当てられたデータは64bitでアクセスできるけど実行速度が遅くなる
そもそも動的なデータは64bitのポインタで管理されるので最初から全アドレスにアクセスできる
>・静的に割り当てられたデータは32bitでアクセスするように制限されてるけど実行速度は速い。
違う、あくまでシンボルを32bitのアドレスとして読み込んでるだけでデータサイズは関係ない
x86_64でも64bitのアドレスを指定して読み込む命令は限られてるし、
実行速度の面でも効率が悪いのでRIP相対で32bit分だけを使ってる
たとえば、
mov rcx, data01
とした場合、data01の部分はRIP相対の32bitアドレスになる、読み込まれるデータは64bitの値
RISC CPUだとアドレスを読み込んでからデータに読み書きするという2段階になるので
たとえば、64bitのARMだと
adrp x0, :pg_hi21:data01
add x0, x0, :lo12:data01
ldr x0, [x0]
と下位33bitでPC相対アドレスとしてシンボルが読み込まれる
RISC-Vの絶対アドレスだと
lui a0, a0, data01
addi a0, a0, data01
ld a0, (a0)
PC相対だと
1: auipc a0, %pcrel_hi(data01)
addi a0, a0, %pcrel_lo(1b)
ld a0, (a0)
こうなる
(%pcrel_lo()では対応するpcrel_hi()のラベルを指定)
117デフォルトの名無しさん
2018/08/19(日) 20:06:20.81ID:XvleiWNb RISC-Vの絶対アドレスのところが間違ってた
不正解
lui a0, a0, data01
addi a0, a0, data01
ld a0, (a0)
正解
lui a0, %hi(data01)
addi a0, a0, %lo(data01)
ld a0, (a0)
不正解
lui a0, a0, data01
addi a0, a0, data01
ld a0, (a0)
正解
lui a0, %hi(data01)
addi a0, a0, %lo(data01)
ld a0, (a0)
118デフォルトの名無しさん
2018/08/20(月) 06:10:04.15ID:yBkytAxc >>116
アドレッシングの話をしているだと思ったのではしょったけどこう書けばいいですかね
・動的に割り当てられたデータは64bitアドレッシングでアクセスできるけど実行速度が遅くなる
・静的に割り当てられたデータは32bitアドレッシングでアクセスするように制限されてるけど実行速度は速い
・どちらの場合も読み書きできるデータサイズに制限はない
・ただしLinuxの場合、メモリモデルを指定して再コンパイルすればこの制限はなくなる
アドレッシングの話をしているだと思ったのではしょったけどこう書けばいいですかね
・動的に割り当てられたデータは64bitアドレッシングでアクセスできるけど実行速度が遅くなる
・静的に割り当てられたデータは32bitアドレッシングでアクセスするように制限されてるけど実行速度は速い
・どちらの場合も読み書きできるデータサイズに制限はない
・ただしLinuxの場合、メモリモデルを指定して再コンパイルすればこの制限はなくなる
119デフォルトの名無しさん
2018/08/20(月) 07:34:26.88ID:VWtXo5Rn 何で、動的に割り当てられた変数と静的に割り当てられた変数の
アクセス速度を比較するのか意味不明だが
一番アクセスが速いのはローカル変数だと思うぞ
ローカル変数はdisplacement付きのスタックポインタ間接アドレッシングでアクセスできるので
ほとんどのCPUでdisplacementが届く範囲なら1命令でロード、ストアができるからね
アクセス速度を比較するのか意味不明だが
一番アクセスが速いのはローカル変数だと思うぞ
ローカル変数はdisplacement付きのスタックポインタ間接アドレッシングでアクセスできるので
ほとんどのCPUでdisplacementが届く範囲なら1命令でロード、ストアができるからね
120デフォルトの名無しさん
2018/08/21(火) 13:09:22.87ID:rmPseMne >>119
今までの話の流れで言うと、速度を比較するのが目的ではなくて、
なぜ静的に割り当てられたデータは32bitアドレッシングでアクセスするように制限されているのか?
ですよ。普通に考えたら64bitアドレッシングが制限なくできて当たり前だろ。なんで?ってことです。
今までの話の流れで言うと、速度を比較するのが目的ではなくて、
なぜ静的に割り当てられたデータは32bitアドレッシングでアクセスするように制限されているのか?
ですよ。普通に考えたら64bitアドレッシングが制限なくできて当たり前だろ。なんで?ってことです。
121デフォルトの名無しさん
2018/08/21(火) 13:14:13.58ID:EQ4qcC3V x86の64bitモードでのアドレッシングは全て64bit
122デフォルトの名無しさん
2018/08/21(火) 16:35:27.52ID:R5Y2p11o123デフォルトの名無しさん
2018/08/21(火) 19:52:55.59ID:JiPBZbts >>120
64bitのデータだろうが32bitデータだろうがデータがキャッシュに入ってれば
キャッシュからデータを読み出す速度は変わらないが、
64bitアドレスを即値で指定すると
CISC CPUの場合、64bitアドレスの分、命令のオペランドの長さが長くなるので
今時の複数の命令を同時発行できるCPUだと一度に発行できる命令の数が減るので遅くなる
64bitのアドレスだけで8バイトにもなるからね
RISC CPUの場合は64bitのアドレスを一度に読み込めないので複数の命令に分けて読み込むが
64bitのアドレスを読み込むと命令数が増える
結局、静的データやジャンプ先のラベルはは32bitアドレスに限定したほうが結果的に速くなる
たいていのプログラムで静的データやジャンプ先のラベルで
32bitの範囲を超えるような応用プログラムは極一部の分野だけだしね
その極一部の応用プログラムのために性能を落とす必要はない
スパコンでも使われるLinuxではメモリモデルとして
静的データやジャンプ先のラベルを64bitで扱うようにコンパイルするオプションがある
このページはPGIのコンパイラのページだがわかりやすく説明してある
https://www.softek.co.jp/SPG/Pgi/TIPS/opt_64.htmlはこのページ
ARMやx86_64、POWERのgccでも-mcmodel=largeや-mcmodel=mediumがあったりする
(ARMでは-mcmodel=largeはあるが-mcmodel=mediumはない)
https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html
https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
https://gcc.gnu.org/onlinedocs/gcc/RS_002f6000-and-PowerPC-Options.html
64bitのデータだろうが32bitデータだろうがデータがキャッシュに入ってれば
キャッシュからデータを読み出す速度は変わらないが、
64bitアドレスを即値で指定すると
CISC CPUの場合、64bitアドレスの分、命令のオペランドの長さが長くなるので
今時の複数の命令を同時発行できるCPUだと一度に発行できる命令の数が減るので遅くなる
64bitのアドレスだけで8バイトにもなるからね
RISC CPUの場合は64bitのアドレスを一度に読み込めないので複数の命令に分けて読み込むが
64bitのアドレスを読み込むと命令数が増える
結局、静的データやジャンプ先のラベルはは32bitアドレスに限定したほうが結果的に速くなる
たいていのプログラムで静的データやジャンプ先のラベルで
32bitの範囲を超えるような応用プログラムは極一部の分野だけだしね
その極一部の応用プログラムのために性能を落とす必要はない
スパコンでも使われるLinuxではメモリモデルとして
静的データやジャンプ先のラベルを64bitで扱うようにコンパイルするオプションがある
このページはPGIのコンパイラのページだがわかりやすく説明してある
https://www.softek.co.jp/SPG/Pgi/TIPS/opt_64.htmlはこのページ
ARMやx86_64、POWERのgccでも-mcmodel=largeや-mcmodel=mediumがあったりする
(ARMでは-mcmodel=largeはあるが-mcmodel=mediumはない)
https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html
https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
https://gcc.gnu.org/onlinedocs/gcc/RS_002f6000-and-PowerPC-Options.html
124デフォルトの名無しさん
2018/08/22(水) 02:39:05.86ID:J61dDDqI >>104
確か、そのリンカオプションは、DLL作成時に指定するとエラーになる。
また、アプリの場合だと、relocation 情報が strip されて、EXE ファイルの中にはなくなっているのに対し、DLLだと relocation 情報が最後まで残されたままになっている。
>>105
あなたが使っている用語が x86 や x64 とは合わずめちゃくちゃなので何を聞いているのか分からないが、
hogehoge db 'xxxx', 0
mov cl, hogehoe 1
とすると、
mov cl,[offset hogehode]
と言う意味になり、encode としては、
mov cl, [RIP + (offset hogehode - offset label1)]
label1:
のように、RIP 相対の disp
mov cl, [RIP + disp32]
に encode される。この場合の disp32 は、意味としては、rel32 で、
RIP からの32BIT相対アドレス。
一方、似て非なるものとして、
mov cl, hogehode[rbx]
とすると、
mov cl, [offset hogehode + rbx]
即ち、
mov cl, [rbx + disp32]
と翻訳される。この場合の、disp32 は、32BIT絶対アドレス。 同じ、disp32 でも、意味は異なる。しかし、disp は、32BITまでで、 64BIT 値のものは存在していない。一方、64BITアドレスも一応は使えるように、
mov REG64, ADDR64 ; REG64 は、RAX, RBX, RCX, EDX, RBP, RSI, EDI など。
や
mov ACC, [ADDR64] ; ACC は、al, ax, eax, rax
という命令が、 専用命令として特別扱いとして存在しているが、特殊中の特殊。
確か、そのリンカオプションは、DLL作成時に指定するとエラーになる。
また、アプリの場合だと、relocation 情報が strip されて、EXE ファイルの中にはなくなっているのに対し、DLLだと relocation 情報が最後まで残されたままになっている。
>>105
あなたが使っている用語が x86 や x64 とは合わずめちゃくちゃなので何を聞いているのか分からないが、
hogehoge db 'xxxx', 0
mov cl, hogehoe 1
とすると、
mov cl,[offset hogehode]
と言う意味になり、encode としては、
mov cl, [RIP + (offset hogehode - offset label1)]
label1:
のように、RIP 相対の disp
mov cl, [RIP + disp32]
に encode される。この場合の disp32 は、意味としては、rel32 で、
RIP からの32BIT相対アドレス。
一方、似て非なるものとして、
mov cl, hogehode[rbx]
とすると、
mov cl, [offset hogehode + rbx]
即ち、
mov cl, [rbx + disp32]
と翻訳される。この場合の、disp32 は、32BIT絶対アドレス。 同じ、disp32 でも、意味は異なる。しかし、disp は、32BITまでで、 64BIT 値のものは存在していない。一方、64BITアドレスも一応は使えるように、
mov REG64, ADDR64 ; REG64 は、RAX, RBX, RCX, EDX, RBP, RSI, EDI など。
や
mov ACC, [ADDR64] ; ACC は、al, ax, eax, rax
という命令が、 専用命令として特別扱いとして存在しているが、特殊中の特殊。
125デフォルトの名無しさん
2018/08/22(水) 02:48:04.81ID:J61dDDqI >>124
訂正:
hogehoge db 'xxxx', 0
mov cl, hogehoge
とすると、
mov cl,[offset hogehoge]
と言う意味になり、encode としては、
mov cl, [RIP + (offset hogehoge - offset label1)]
label1:
のように、RIP 相対の disp
mov cl, [RIP + disp32]
に encode される。この場合の disp32 は、意味としては、rel32 で、
RIP からの32BIT相対アドレス。
ちなみに、masm では、
hoge1 db 'aaa' ;1
と
hoge2: db 'aaa' ;2
は明確に区別されており、hoge1 は、byte 型の配列変数のような取り扱いになり、
mov al, hoge1 ;1
は、masm には通らないが、旧来のアセンブラの感覚で言えば、意味的には、
mov al, qword [offset hoge1] ;3
となり、hoge2 の方は、直後の db 命令とは全く関係の無い単なる near アドレスと解釈され、
mov rax, hoge2 ;4
は、意味的には、
mov rax, offset hoge2 ;5
となる、ただし、4は、もしかするとそれ自体が文法上、masm の構文に合わないかもしれない。
masm は、「マクロアセンブラ」であって、通常のアセンブラとは結構異なるので。
訂正:
hogehoge db 'xxxx', 0
mov cl, hogehoge
とすると、
mov cl,[offset hogehoge]
と言う意味になり、encode としては、
mov cl, [RIP + (offset hogehoge - offset label1)]
label1:
のように、RIP 相対の disp
mov cl, [RIP + disp32]
に encode される。この場合の disp32 は、意味としては、rel32 で、
RIP からの32BIT相対アドレス。
ちなみに、masm では、
hoge1 db 'aaa' ;1
と
hoge2: db 'aaa' ;2
は明確に区別されており、hoge1 は、byte 型の配列変数のような取り扱いになり、
mov al, hoge1 ;1
は、masm には通らないが、旧来のアセンブラの感覚で言えば、意味的には、
mov al, qword [offset hoge1] ;3
となり、hoge2 の方は、直後の db 命令とは全く関係の無い単なる near アドレスと解釈され、
mov rax, hoge2 ;4
は、意味的には、
mov rax, offset hoge2 ;5
となる、ただし、4は、もしかするとそれ自体が文法上、masm の構文に合わないかもしれない。
masm は、「マクロアセンブラ」であって、通常のアセンブラとは結構異なるので。
126デフォルトの名無しさん
2018/08/22(水) 02:50:10.88ID:J61dDDqI >>125
誤: mov al, qword [offset hoge1] ;3
正: mov al, byte [offset hoge1] ;3
これも、masm 流には、
mov al, byte ptr [offset hoge1] ;3
nasm 流には、
mov.b al, [offset hoge1] ;3
みたいな感覚。みたいなだけで、実際にはそのまま書くと、エラーになる
かも知れない。
誤: mov al, qword [offset hoge1] ;3
正: mov al, byte [offset hoge1] ;3
これも、masm 流には、
mov al, byte ptr [offset hoge1] ;3
nasm 流には、
mov.b al, [offset hoge1] ;3
みたいな感覚。みたいなだけで、実際にはそのまま書くと、エラーになる
かも知れない。
127デフォルトの名無しさん
2018/08/22(水) 02:55:16.05ID:J61dDDqI >>124
さらに補足すると、
mov cl, [rbx + disp32]
の disp32 は、rbx の中身によって意味が変わってきて、
1. disp = 32BIT 相対アドレス (rbx が絶対アドレスの場合)
2. disp = 32BIT 絶対アドレス (rbx が相対アドレスの場合)
となる。2. の例としては、
rbx = 配列添え字 * (配列の要素のバイト数)
のような場合。1. の例としては、
rbx = 構造体の先頭アドレス
のような場合。
さらに補足すると、
mov cl, [rbx + disp32]
の disp32 は、rbx の中身によって意味が変わってきて、
1. disp = 32BIT 相対アドレス (rbx が絶対アドレスの場合)
2. disp = 32BIT 絶対アドレス (rbx が相対アドレスの場合)
となる。2. の例としては、
rbx = 配列添え字 * (配列の要素のバイト数)
のような場合。1. の例としては、
rbx = 構造体の先頭アドレス
のような場合。
128デフォルトの名無しさん
2018/08/22(水) 04:37:08.89ID:8qwUBnhH >>127
今やってみたが
64bitアプリを通常にコンパイルした場合のWinMainのアドレス
0x000000013f291770
/largeaddressaware:noを付けてコンパイルした場合のWinMainのアドレス
0x0000000001241770
/largeaddressaware:noを付けるとプログラムがロードされるアドレスが変わる
64bitのアプリを通常にコンパイルするとWinMainのアドレスが0x000000013f291770
およそ先頭から5GBの位置
つまり、32bit絶対アドレスでは届かない位置にプログラムがロードされてる
/largeaddressaware:noをつけると先頭から18MBくらいの位置
エラーが出るのは32bit絶対アドレスでは届かない位置にロードされる可能性があるからだろうな
今やってみたが
64bitアプリを通常にコンパイルした場合のWinMainのアドレス
0x000000013f291770
/largeaddressaware:noを付けてコンパイルした場合のWinMainのアドレス
0x0000000001241770
/largeaddressaware:noを付けるとプログラムがロードされるアドレスが変わる
64bitのアプリを通常にコンパイルするとWinMainのアドレスが0x000000013f291770
およそ先頭から5GBの位置
つまり、32bit絶対アドレスでは届かない位置にプログラムがロードされてる
/largeaddressaware:noをつけると先頭から18MBくらいの位置
エラーが出るのは32bit絶対アドレスでは届かない位置にロードされる可能性があるからだろうな
129デフォルトの名無しさん
2018/08/22(水) 04:40:24.11ID:8qwUBnhH 補足:
/largeaddressaware:noを付けると64bitアプリでもメモリは2GBまでしか使えなくなる
/largeaddressaware:noを付けると64bitアプリでもメモリは2GBまでしか使えなくなる
130デフォルトの名無しさん
2018/08/22(水) 04:46:45.21ID:8qwUBnhH つまり、>>128が示してることは
Windowsの64bitアプリでは
mov al,my_mojiretu[rbx]
のような書き方はしてはいけないということ
Windowsの64bitアプリでは
mov al,my_mojiretu[rbx]
のような書き方はしてはいけないということ
131デフォルトの名無しさん
2018/08/22(水) 08:30:00.67ID:WDZbf6Te >>124 XvleiWNbとは別人だよね?
/LARGEADDRESSAWARE:NOの辺りからなんか違和感あって、「そうなん?」って感じだったんだけど。
ARMやコンパイラの仕様だとかまで出てきて訳わからなくなるところだったよ。
>一方、似て非なるものとして、
> mov cl, hogehode[rbx]
>とすると、
> mov cl, [offset hogehode + rbx]
>即ち、
> mov cl, [rbx + disp32]
>と翻訳される。この場合の、disp32 は、32BIT絶対アドレス。 同じ、disp32 でも、意味は異なる。
>Windowsの64bitアプリでは
>mov al,my_mojiretu[rbx]
>のような書き方はしてはいけないということ
今までなんで絶対アドレスが出てくるのか疑問だったけど、コンパイラはこういうコードは吐かない、ってことだよね。
/LARGEADDRESSAWARE:NOの辺りからなんか違和感あって、「そうなん?」って感じだったんだけど。
ARMやコンパイラの仕様だとかまで出てきて訳わからなくなるところだったよ。
>一方、似て非なるものとして、
> mov cl, hogehode[rbx]
>とすると、
> mov cl, [offset hogehode + rbx]
>即ち、
> mov cl, [rbx + disp32]
>と翻訳される。この場合の、disp32 は、32BIT絶対アドレス。 同じ、disp32 でも、意味は異なる。
>Windowsの64bitアプリでは
>mov al,my_mojiretu[rbx]
>のような書き方はしてはいけないということ
今までなんで絶対アドレスが出てくるのか疑問だったけど、コンパイラはこういうコードは吐かない、ってことだよね。
132デフォルトの名無しさん
2018/08/22(水) 19:32:17.75ID:J61dDDqI133デフォルトの名無しさん
2018/08/22(水) 19:39:47.75ID:J61dDDqI >>130
でも現実は、複雑。
なぜなら、COFFの仕様的には、obj ではない Image(EXEやDLLの事) のためだけに
ある .reloc section には、64BIT 絶対アドレスの再配置も行えるようになっているから。
現状の MS 製の link.exe がどうなっているかはともかく。
でも現実は、複雑。
なぜなら、COFFの仕様的には、obj ではない Image(EXEやDLLの事) のためだけに
ある .reloc section には、64BIT 絶対アドレスの再配置も行えるようになっているから。
現状の MS 製の link.exe がどうなっているかはともかく。
134デフォルトの名無しさん
2018/08/22(水) 19:45:45.82ID:J61dDDqI >>133
すまん。間違った。
mov al,my_mojiretu[rbx]
は、意味的には、
mov al, [rbx + offset my_mojiretu]
となって、最後は、
mov al, [rbx + disp32]
となるが、disp32 の部分は、disp64 の命令は存在していないので、
.reloc section が 64BIT 絶対アドレスに対応していても、無理だった。
勘違いした。
すまん。間違った。
mov al,my_mojiretu[rbx]
は、意味的には、
mov al, [rbx + offset my_mojiretu]
となって、最後は、
mov al, [rbx + disp32]
となるが、disp32 の部分は、disp64 の命令は存在していないので、
.reloc section が 64BIT 絶対アドレスに対応していても、無理だった。
勘違いした。
135デフォルトの名無しさん
2018/08/22(水) 19:57:50.56ID:J61dDDqI >>128
一応、論理的には、WinMain は、code (.text) section に置かれる。
my_mojiretu みたいなものは、.data section (など)に置かれる。
my_mojiretu みたいなものは、初期化(初期値)データなので、
2GB も使えれば十分ではあるはず。もし、2GB を超えるのなら、exe ファイルの
サイズも 2GB を超えるはず。
という事で、初期化データのおかれた section のアドレスが、2GB 未満
に置かれるならなんとかなるはず。
というか、通常、exe ファイルは、relocation 情報が strip されているので、
確か、Optional Header の BaseOfCode に配置したいアドレスを入れておける。
だから、その値を小さめにしておけば、初期化データのアドレスを 2GB 未満
の位置に配置する事はそんなに難しくないはず。
確か、32BIT 時代は、0x40000 位の値だった。
一応、論理的には、WinMain は、code (.text) section に置かれる。
my_mojiretu みたいなものは、.data section (など)に置かれる。
my_mojiretu みたいなものは、初期化(初期値)データなので、
2GB も使えれば十分ではあるはず。もし、2GB を超えるのなら、exe ファイルの
サイズも 2GB を超えるはず。
という事で、初期化データのおかれた section のアドレスが、2GB 未満
に置かれるならなんとかなるはず。
というか、通常、exe ファイルは、relocation 情報が strip されているので、
確か、Optional Header の BaseOfCode に配置したいアドレスを入れておける。
だから、その値を小さめにしておけば、初期化データのアドレスを 2GB 未満
の位置に配置する事はそんなに難しくないはず。
確か、32BIT 時代は、0x40000 位の値だった。
136デフォルトの名無しさん
2018/08/22(水) 20:02:29.70ID:J61dDDqI >>135
正しくは、BaseOfCode ではなく、ImageBase の方だった。
正しい値は、0x40000 ではなく、1桁大きい、0x400000 だった。
64BIT COFF では、変わってるかもしれない。確か、PREFERED_BASE
などという名前も記憶にある。
ImageBase Preferred address of first byte of image when loaded into memory;
must be a multiple of 64K. The default for DLLs is 0x10000000.
The default for Windows CE EXEs is 0x00010000.
The default for Windows NT, Windows 95, and Windows 98 is 0x00400000.
正しくは、BaseOfCode ではなく、ImageBase の方だった。
正しい値は、0x40000 ではなく、1桁大きい、0x400000 だった。
64BIT COFF では、変わってるかもしれない。確か、PREFERED_BASE
などという名前も記憶にある。
ImageBase Preferred address of first byte of image when loaded into memory;
must be a multiple of 64K. The default for DLLs is 0x10000000.
The default for Windows CE EXEs is 0x00010000.
The default for Windows NT, Windows 95, and Windows 98 is 0x00400000.
137デフォルトの名無しさん
2018/08/22(水) 20:11:19.88ID:J61dDDqI >>128
自分の勘だと、そのアドレスは、WinMain よりも、DLL の DllMain が置かれるような
値になってるね。
不思議だ。WinMain をそんな大きなアドレスに置く必要性は余り無いハズなので。
初期化データが 2GB 未満に置かれていても、malloc() や、new で確保されるデータは、
64BIT アドレスにできるはずだし。なお、
1_3f29_1770
↑は、32BIT を超えて、33BIT の値だな・・・。なんちゅう大きな値だろう。
自分の勘だと、そのアドレスは、WinMain よりも、DLL の DllMain が置かれるような
値になってるね。
不思議だ。WinMain をそんな大きなアドレスに置く必要性は余り無いハズなので。
初期化データが 2GB 未満に置かれていても、malloc() や、new で確保されるデータは、
64BIT アドレスにできるはずだし。なお、
1_3f29_1770
↑は、32BIT を超えて、33BIT の値だな・・・。なんちゅう大きな値だろう。
138デフォルトの名無しさん
2018/08/22(水) 20:46:10.32ID:dx23aElG 64bitもアドレス空間があるんだから
多少大きくても何の問題も無いだろ
多少大きくても何の問題も無いだろ
139デフォルトの名無しさん
2018/08/22(水) 21:22:24.95ID:WDZbf6Te >>134
32bitのフラットメモリモデルだと、静的変数はイメージにはオフセットを入れといて、
実行時にローダで書き換えてたんだと思うんだけど、64bitでは絶対アドレスは制約が大きくなるから変だと思ったんだ。
絶対アドレスはコンパイラでも使えなくはないけど、デバイスドライバでメモリマップトI/O操作するような時しか使わないと思う。
64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
mov al,my_mojiretu[rbx]
みたいなコードが例外吐いて特定困難なバグが発生するのを防止してるのでは?
32bitのフラットメモリモデルだと、静的変数はイメージにはオフセットを入れといて、
実行時にローダで書き換えてたんだと思うんだけど、64bitでは絶対アドレスは制約が大きくなるから変だと思ったんだ。
絶対アドレスはコンパイラでも使えなくはないけど、デバイスドライバでメモリマップトI/O操作するような時しか使わないと思う。
64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
mov al,my_mojiretu[rbx]
みたいなコードが例外吐いて特定困難なバグが発生するのを防止してるのでは?
140デフォルトの名無しさん
2018/08/22(水) 21:24:18.64ID:WDZbf6Te 例外吐くことで
141デフォルトの名無しさん
2018/08/23(木) 05:44:12.90ID:sOVf8lyT >>135
コマンドライン用の簡単なC言語の64bitのプログラムで試したが
main関数のアドレス=0x000000013f7f1000
data sectionで定義した変数data01のアドレス=0x000000013f7fc087
だったぞ
完全に32bit絶対アドレスの範囲を超えてる
コマンドライン用の簡単なC言語の64bitのプログラムで試したが
main関数のアドレス=0x000000013f7f1000
data sectionで定義した変数data01のアドレス=0x000000013f7fc087
だったぞ
完全に32bit絶対アドレスの範囲を超えてる
142デフォルトの名無しさん
2018/08/23(木) 07:08:50.83ID:sOVf8lyT 64bitのWindowsアプリを作って.data sectionの変数のアドレスも表示してみた
WinMain address = 0x000000013fd419a0
data sectionの変数のアドレス
data01 address = 0x000000013fd4d000
/largeaddressaware:noを付けた場合
WinMain address = 0x00000000013619a0
data sectionの変数のアドレス
data01 address = 0x000000000136d000
WinMain address = 0x000000013fd419a0
data sectionの変数のアドレス
data01 address = 0x000000013fd4d000
/largeaddressaware:noを付けた場合
WinMain address = 0x00000000013619a0
data sectionの変数のアドレス
data01 address = 0x000000000136d000
143デフォルトの名無しさん
2018/08/23(木) 07:09:02.23ID:4LRopBJn >>139
>64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
>mov al,my_mojiretu[rbx]
>みたいなコードが例外吐いて特定困難なバグが発生するのを防止してるのでは?
意味不明だ。別に、
mov al,my_mojiretu[rbx]
というコードが悪いわけではない。
むしろ、最適化のためには使った方が効率が良くなる。
>64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
>mov al,my_mojiretu[rbx]
>みたいなコードが例外吐いて特定困難なバグが発生するのを防止してるのでは?
意味不明だ。別に、
mov al,my_mojiretu[rbx]
というコードが悪いわけではない。
むしろ、最適化のためには使った方が効率が良くなる。
144デフォルトの名無しさん
2018/08/23(木) 07:22:22.74ID:4LRopBJn >>141-142
もしそうだとすると、VC++ の吐くコードがx64の命令を上手く使いきれてないという事になる。
本来であれば、アドレスの配置を上手く行うだけで、64BIT モードでも特に問題なく
mov al,my_mojiretu[rbx]
という命令は使えて、かつ、64BIT アドレスの制限を受けるわけでもないのだから。
ちなみに、アプリの EXE は、リンク後は固定アドレスで、ローダーがアドレスを再配置
する事はない。だから、ImageBase を小さい値になるようにリンクしさえすれば、
問題が生じない。
もしそうだとすると、VC++ の吐くコードがx64の命令を上手く使いきれてないという事になる。
本来であれば、アドレスの配置を上手く行うだけで、64BIT モードでも特に問題なく
mov al,my_mojiretu[rbx]
という命令は使えて、かつ、64BIT アドレスの制限を受けるわけでもないのだから。
ちなみに、アプリの EXE は、リンク後は固定アドレスで、ローダーがアドレスを再配置
する事はない。だから、ImageBase を小さい値になるようにリンクしさえすれば、
問題が生じない。
145デフォルトの名無しさん
2018/08/23(木) 07:27:31.64ID:4LRopBJn >>139
>64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
通常、コンピュータソフト、特にOSのセキュリティーというのは、そういう人間的なもの
ではなくて、もっと厳密な物だ。
ランダマイズして撹乱して相手の目をくらます、などという方法は通常取られない。
実際、EXE ファイルを解析した経験からしても、ランダマイズなどは全く行われていない。
何回リンクしても、同じアセンブリソースや、同じC++ソースなら、全く同じアドレスになる。
異なるソースであっても、ベースアドレスなどは、ほとんどの場合、固定値。
>64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
通常、コンピュータソフト、特にOSのセキュリティーというのは、そういう人間的なもの
ではなくて、もっと厳密な物だ。
ランダマイズして撹乱して相手の目をくらます、などという方法は通常取られない。
実際、EXE ファイルを解析した経験からしても、ランダマイズなどは全く行われていない。
何回リンクしても、同じアセンブリソースや、同じC++ソースなら、全く同じアドレスになる。
異なるソースであっても、ベースアドレスなどは、ほとんどの場合、固定値。
146デフォルトの名無しさん
2018/08/23(木) 07:58:52.05ID:4LRopBJn >>138
実際には問題がある。なぜなら、そんなにアドレスが大きいと、さっきから話題の
mov al, my_mojiretu[rbx]
という命令が使えなくなるからだ。
これは、グローバルな配列変数を、添え字でアクセスするような場合に良いコードに
なる事がある。僅かではあるが。もし、この命令が使えないとなると、
mov rdx,offset my_mojiretu
mov al,[rdx + rbx]
のように、2つの命令を使わなくてはならなくなり、最適化上、不利になる。
実際には問題がある。なぜなら、そんなにアドレスが大きいと、さっきから話題の
mov al, my_mojiretu[rbx]
という命令が使えなくなるからだ。
これは、グローバルな配列変数を、添え字でアクセスするような場合に良いコードに
なる事がある。僅かではあるが。もし、この命令が使えないとなると、
mov rdx,offset my_mojiretu
mov al,[rdx + rbx]
のように、2つの命令を使わなくてはならなくなり、最適化上、不利になる。
147デフォルトの名無しさん
2018/08/23(木) 08:10:29.27ID:wxGNRrqx そんな事言い出したら
4GBや64KBに限定した方が小さいコードになるから
compactモデルにしよう
とかいう話にもなる
昔に戻りたい?
何のための64bit?
4GBや64KBに限定した方が小さいコードになるから
compactモデルにしよう
とかいう話にもなる
昔に戻りたい?
何のための64bit?
148デフォルトの名無しさん
2018/08/23(木) 08:22:23.99ID:4LRopBJn >>147
だから、そういうことじゃなく、EXEファイルの中に、2GBを越える初期化データを
誰が入れたいかって話なんだ。
別に、ImageBase を小さい値にしていても、malloc() や、new するデータは、
6GBでも理論上は確保できるわけで、制限されるのは、EXEファイルの中の
初期化データのサイズが2GBまで、ってだけなんだ。
それで、使えるマシン語の間接オペランドの種類が1つ増やせる。
mov 命令だけでなく、add, sub, mul, div, idiv, lea, addps, addss などにも
全て影響する貴重な間接オペランド。
だから、そういうことじゃなく、EXEファイルの中に、2GBを越える初期化データを
誰が入れたいかって話なんだ。
別に、ImageBase を小さい値にしていても、malloc() や、new するデータは、
6GBでも理論上は確保できるわけで、制限されるのは、EXEファイルの中の
初期化データのサイズが2GBまで、ってだけなんだ。
それで、使えるマシン語の間接オペランドの種類が1つ増やせる。
mov 命令だけでなく、add, sub, mul, div, idiv, lea, addps, addss などにも
全て影響する貴重な間接オペランド。
149デフォルトの名無しさん
2018/08/23(木) 08:46:40.08ID:4LRopBJn >>147
8086時代の 64KB では制限が大きすぎて、ほとんどのプログラムで、制限が足かせ
になっていたので、32BIT になって、アドレスが 4GB に拡張されて非常に便利になった。
ところが、64BIT 時代になっても、そのときのようなメリットが無いと思うんだ。
AMD vs Intel の競争の結果出てきた産物かも知れない。そういうの、時々ある。
8086時代の 64KB では制限が大きすぎて、ほとんどのプログラムで、制限が足かせ
になっていたので、32BIT になって、アドレスが 4GB に拡張されて非常に便利になった。
ところが、64BIT 時代になっても、そのときのようなメリットが無いと思うんだ。
AMD vs Intel の競争の結果出てきた産物かも知れない。そういうの、時々ある。
150デフォルトの名無しさん
2018/08/23(木) 08:56:25.66ID:K9a3gVgQ >>145
WindowsではASLRでランダム化普通にやってるらしいですよ
http://07c00.hatenablog.com/entry/2013/08/07/033443
OSがプロセスをロードするときに、ランダムな場所にモジュールを配置するセキュリティ機能です。
実際はモジュールだけじゃなく、スタックやヒープなどもランダマイズされたりします。
WindowsではASLRでランダム化普通にやってるらしいですよ
http://07c00.hatenablog.com/entry/2013/08/07/033443
OSがプロセスをロードするときに、ランダムな場所にモジュールを配置するセキュリティ機能です。
実際はモジュールだけじゃなく、スタックやヒープなどもランダマイズされたりします。
151デフォルトの名無しさん
2018/08/23(木) 09:03:22.89ID:4LRopBJn >>150
少なくとも、EXE の .text, .data セクションは再配置される事は無いはず。
なぜなら、.reloc section が存在せず、再配置する事が原理的に出来なくなっているから。
DLL は、.reloc section が残されているので再配置できる。ただし、再配置しなくても、
全てのシステムのDLLは、最初からアドレスが重ならないような ImageBase になっている
ので、再配置されずにそのままおかれるのが、昔は基本であった。
少なくとも、EXE の .text, .data セクションは再配置される事は無いはず。
なぜなら、.reloc section が存在せず、再配置する事が原理的に出来なくなっているから。
DLL は、.reloc section が残されているので再配置できる。ただし、再配置しなくても、
全てのシステムのDLLは、最初からアドレスが重ならないような ImageBase になっている
ので、再配置されずにそのままおかれるのが、昔は基本であった。
152デフォルトの名無しさん
2018/08/23(木) 10:25:25.69ID:3bgfj1QZ153デフォルトの名無しさん
2018/08/23(木) 11:01:43.32ID:4LRopBJn >>152
じゃあなんで、MS純正VSは、いまだに 32BIT コードで動いてるのさ。
x64 は、レジスタが増えた事と、memmove() などが多分、倍の速度で動く事が
最大のメリットじゃないの?
アドレス幅が64BITになって現実的なメリットはどこにあるのかな?
じゃあなんで、MS純正VSは、いまだに 32BIT コードで動いてるのさ。
x64 は、レジスタが増えた事と、memmove() などが多分、倍の速度で動く事が
最大のメリットじゃないの?
アドレス幅が64BITになって現実的なメリットはどこにあるのかな?
154デフォルトの名無しさん
2018/08/23(木) 11:36:32.13ID:3bgfj1QZ なにが「じゃあ」だか
メリットが無いと思うなら2GB限定のアプリにすれば良い
って書いたのが見えなかった?
メリットが無いと思うなら2GB限定のアプリにすれば良い
って書いたのが見えなかった?
155デフォルトの名無しさん
2018/08/23(木) 12:51:14.26ID:4LRopBJn >>154
だから、メリットはあるよ。
レジスタが増えること、AVX, AVX2, AVX512 で、YMM, ZMM レジスタでベクトル
の次元が大きくなったSIMD 命令が使えること、3オペランドの以上のSIMD命令が使える
事、メモリ転送の速度が倍近くになること。malloc(), new が、2GB を超えて行える事。
初期化サイズが2GBを越えるメリットは余り無いと思ってるけど。
だから、メリットはあるよ。
レジスタが増えること、AVX, AVX2, AVX512 で、YMM, ZMM レジスタでベクトル
の次元が大きくなったSIMD 命令が使えること、3オペランドの以上のSIMD命令が使える
事、メモリ転送の速度が倍近くになること。malloc(), new が、2GB を超えて行える事。
初期化サイズが2GBを越えるメリットは余り無いと思ってるけど。
158デフォルトの名無しさん
2018/08/23(木) 18:36:50.55ID:wxGNRrqx >>155
2G限定と関係ないじゃん
2G限定と関係ないじゃん
159デフォルトの名無しさん
2018/08/23(木) 19:03:15.16ID:sOVf8lyT >>148
結局、
mov al,my_mojiretu[rbx]
こんなコードを書くと64bitではLINKする時にエラーが出る
/largeaddressaware:noを指定するとLINKでエラーは出なくなるが、
/largeaddressaware:noを指定すると動的メモリも含め2GB以下のメモリしか扱えなくなる
結局、
mov al,my_mojiretu[rbx]
こんなコードを書くと64bitではLINKする時にエラーが出る
/largeaddressaware:noを指定するとLINKでエラーは出なくなるが、
/largeaddressaware:noを指定すると動的メモリも含め2GB以下のメモリしか扱えなくなる
160デフォルトの名無しさん
2018/08/23(木) 19:09:33.40ID:QrjyoFcH なんかしらあるんじゃね
161デフォルトの名無しさん
2018/08/23(木) 19:30:53.52ID:k97Awv43162デフォルトの名無しさん
2018/08/23(木) 19:47:44.13ID:sOVf8lyT 32bit Windowsは切り捨てに入ってきてるからね
ゲームでも64bit版のみのも出てきてる
NVIDIA、GPUドライバーの32bit版OSサポートを終了へ 〜次期版からは64bit版だけに
https://forest.watch.impress.co.jp/docs/news/1098673.html
ゲームでも64bit版のみのも出てきてる
NVIDIA、GPUドライバーの32bit版OSサポートを終了へ 〜次期版からは64bit版だけに
https://forest.watch.impress.co.jp/docs/news/1098673.html
163デフォルトの名無しさん
2018/08/23(木) 19:52:19.27ID:sOVf8lyT バーチャルYoutuberなんかでも使われるソフト(エロゲ)だが
64bit Windowsのみ対応
動画配信などで結構使われてる
CUSTOM ORDER MAID 3D2
http://com3d2.jp/main.html
OS Windows® 7/8.1/10 全て64bitのみ対応 ※6
※6:32bitOSには対応しておりません。
64bit Windowsのみ対応
動画配信などで結構使われてる
CUSTOM ORDER MAID 3D2
http://com3d2.jp/main.html
OS Windows® 7/8.1/10 全て64bitのみ対応 ※6
※6:32bitOSには対応しておりません。
164デフォルトの名無しさん
2018/08/23(木) 20:04:05.41ID:k97Awv43165デフォルトの名無しさん
2018/08/23(木) 20:05:15.44ID:sOVf8lyT >>153
10年位前に出来たオンラインゲームでも、今はもう2GBのメモリだともう足りなくて
32bitのゲームでも/LARGEADDRESSAWAREのフラグ立てて延命してるのもあるよ
64bit WindowsならLAAフラグを立てると32bitアプリでも4GBまで使えるようになる
LAAで延命してるゲームで32bit Windowsで遊ぶとメモリ不足で高確率で落ちるゲームとか既にある
10年位前に出来たオンラインゲームでも、今はもう2GBのメモリだともう足りなくて
32bitのゲームでも/LARGEADDRESSAWAREのフラグ立てて延命してるのもあるよ
64bit WindowsならLAAフラグを立てると32bitアプリでも4GBまで使えるようになる
LAAで延命してるゲームで32bit Windowsで遊ぶとメモリ不足で高確率で落ちるゲームとか既にある
166デフォルトの名無しさん
2018/08/23(木) 20:12:15.30ID:sOVf8lyT こんな記事が出るくらい、2GBではメモリが足りなくなってるアプリがたくさんあるぞ
64bit Windowsを前提とした32bitアプリケーション延命法
〜 LAAオプションで32bitアプリケーションのメモリ不足問題を解消
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
64bit Windowsを前提とした32bitアプリケーション延命法
〜 LAAオプションで32bitアプリケーションのメモリ不足問題を解消
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
167デフォルトの名無しさん
2018/08/23(木) 20:12:19.28ID:k97Awv43 なぜ確率の問題?
168デフォルトの名無しさん
2018/08/23(木) 20:16:43.95ID:sOVf8lyT ちなみにこのブログ書いてるところはWindows用ソフトもいくつか出してるところだよ
169デフォルトの名無しさん
2018/08/23(木) 20:18:49.99ID:sOVf8lyT170デフォルトの名無しさん
2018/08/23(木) 20:23:47.22ID:k97Awv43 質問に全く答えてない件
171デフォルトの名無しさん
2018/08/23(木) 20:34:21.09ID:sOVf8lyT >>146
実際にどの程度、速度が変わるのか試してみて欲しいもんだな
ただの机上の空論じゃないのか?
大体、配列で何回もデータにアクセスするなら
32bitのDISPを毎回指定するオーバヘッドだってあるんだが
実際にどの程度、速度が変わるのか試してみて欲しいもんだな
ただの机上の空論じゃないのか?
大体、配列で何回もデータにアクセスするなら
32bitのDISPを毎回指定するオーバヘッドだってあるんだが
172デフォルトの名無しさん
2018/08/23(木) 21:08:22.26ID:wxGNRrqx 32bitアプリも2G限定アプリも32bit OSも絶滅して良い
Windowsの話
Windowsの話
173デフォルトの名無しさん
2018/08/23(木) 21:13:40.67ID:sOVf8lyT mov rcx, offset HOGEHOGE01
mov rax, qword ptr [rcx + rbx]
mov rax, qword ptr [rcx + rbx]
mov rax, qword ptr [rcx + rbx]
mov rax, qword ptr [rcx + rbx]
これと
mov rax, HOGEHOGE01[rbx]
mov rax, HOGEHOGE01[rbx]
mov rax, HOGEHOGE01[rbx]
mov rax, HOGEHOGE01[rbx]
これを250個並べて1000万回ループさせてみたが、1%くらいしか差はないよ
mov rax, qword ptr [rcx + rbx]
mov rax, qword ptr [rcx + rbx]
mov rax, qword ptr [rcx + rbx]
mov rax, qword ptr [rcx + rbx]
これと
mov rax, HOGEHOGE01[rbx]
mov rax, HOGEHOGE01[rbx]
mov rax, HOGEHOGE01[rbx]
mov rax, HOGEHOGE01[rbx]
これを250個並べて1000万回ループさせてみたが、1%くらいしか差はないよ
174デフォルトの名無しさん
2018/08/23(木) 21:28:42.56ID:wxGNRrqx 250個並べてキャッシュに収まる?
175デフォルトの名無しさん
2018/08/24(金) 00:12:57.34ID:568m+iHd なんで訳分からなくなりそうになったのか理解できたw
4LRopBJnが変なんだな。
Microsoftが64bitでは絶対アドレスのインデックスは使わないって決めたんだから、その流儀に従うのが高級言語とリンクだよ。
4LRopBJnが変なんだな。
Microsoftが64bitでは絶対アドレスのインデックスは使わないって決めたんだから、その流儀に従うのが高級言語とリンクだよ。
176デフォルトの名無しさん
2018/08/24(金) 00:23:58.73ID:568m+iHd177デフォルトの名無しさん
2018/08/24(金) 01:48:40.54ID:PMMpdZPT178デフォルトの名無しさん
2018/08/24(金) 01:50:43.81ID:PMMpdZPT >>159
いや、それはあなたの勘違い。
そのオプションを指定しても、EXEの中に入っている「初期化データ」のアドレス
が2GB以下に限定されるだけで、動的メモリは、理論上は、100GB でも一気に
確保できる。それは、再三言ってる。あなたは理解出来てないと思う。
いや、それはあなたの勘違い。
そのオプションを指定しても、EXEの中に入っている「初期化データ」のアドレス
が2GB以下に限定されるだけで、動的メモリは、理論上は、100GB でも一気に
確保できる。それは、再三言ってる。あなたは理解出来てないと思う。
179デフォルトの名無しさん
2018/08/24(金) 01:54:49.18ID:PMMpdZPT >>164
再三言ってるけど、あの/LARGEADDRESSAWARE:NO オプションを
付けても、「初期化データ」のアドレスが2GBに制限されるだけで、
new や malloc() などの、ヒープから確保される動的メモリは、64GBの
アドレス空間どこにあっても問題ないんだよ。
再三言ってるけど、あの/LARGEADDRESSAWARE:NO オプションを
付けても、「初期化データ」のアドレスが2GBに制限されるだけで、
new や malloc() などの、ヒープから確保される動的メモリは、64GBの
アドレス空間どこにあっても問題ないんだよ。
180デフォルトの名無しさん
2018/08/24(金) 02:00:34.30ID:PMMpdZPT >>173
そりゃ分かってるよ。
でも逆に、EXEファイルの中に最初から入っている「初期化データ」
の2GB制限とどっちが良いかの話になるんだよ。もちろん、動的メモリ
は何の制限も受けず、64GBアドレスが好きなように使える。
初期化データというのは、何かの埋め込みテーブルのための配列
だとか、文字列データとか、そういうものだよ。
巨大な3Dモデルデータ、テクスチャ、マップデータなどは、外部ファイル
にでも置いておけば、2GBの制限は受けず、仮想アドレスとしては
64BITまるまる使えるから。
実際、EXEの中にある初期化データが2GBを越えるという事は、
EXEファイルが2GBを越えるという事だから、そのアプリの起動
時には、有無を言わさず HDDなどから、2GBの読み込みが
始まってしまうことになる。
そりゃ分かってるよ。
でも逆に、EXEファイルの中に最初から入っている「初期化データ」
の2GB制限とどっちが良いかの話になるんだよ。もちろん、動的メモリ
は何の制限も受けず、64GBアドレスが好きなように使える。
初期化データというのは、何かの埋め込みテーブルのための配列
だとか、文字列データとか、そういうものだよ。
巨大な3Dモデルデータ、テクスチャ、マップデータなどは、外部ファイル
にでも置いておけば、2GBの制限は受けず、仮想アドレスとしては
64BITまるまる使えるから。
実際、EXEの中にある初期化データが2GBを越えるという事は、
EXEファイルが2GBを越えるという事だから、そのアプリの起動
時には、有無を言わさず HDDなどから、2GBの読み込みが
始まってしまうことになる。
181デフォルトの名無しさん
2018/08/24(金) 02:02:34.25ID:PMMpdZPT182デフォルトの名無しさん
2018/08/24(金) 02:18:09.88ID:PMMpdZPT >>173
それでもやはり、1%の速度低下にはなったんだよね。
「初期化データの2GB制限」は、現実的には何の制限にもなってない
事は理解出来てる???? 動的メモリは、64BIT 自由に使える
んだよ。
それでもやはり、1%の速度低下にはなったんだよね。
「初期化データの2GB制限」は、現実的には何の制限にもなってない
事は理解出来てる???? 動的メモリは、64BIT 自由に使える
んだよ。
183デフォルトの名無しさん
2018/08/24(金) 04:19:33.40ID:CXKCSzYg184デフォルトの名無しさん
2018/08/24(金) 04:38:15.52ID:CXKCSzYg >>182
実際に試したことないのが丸わかり
/largeaddressaware:noをつけると本当に試してみるといいよ、
動的メモリも2GB以下しか確保できなくなるから
このページの
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
この図に載ってるプログラムでも試せるよ
https://www.webtech.co.jp/blog/wp-content/uploads/2013/11/laa_test_prg_thumb.png
実際に試したことないのが丸わかり
/largeaddressaware:noをつけると本当に試してみるといいよ、
動的メモリも2GB以下しか確保できなくなるから
このページの
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
この図に載ってるプログラムでも試せるよ
https://www.webtech.co.jp/blog/wp-content/uploads/2013/11/laa_test_prg_thumb.png
185デフォルトの名無しさん
2018/08/24(金) 04:39:04.29ID:CXKCSzYg 上のプログラムだと/largeaddressaware:noを付けない時に
無限に確保するので4500MBで終わるように少し改変してみた
これで試してみな
#include <windows.h>
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmd, int n)
{
int step = 10; //10MB
int count = 0;
char temp[20];
for (;;)
{
void *p = GlobalAlloc(GPTR, step * 1024 * 1024);
if (p == NULL)
{
break;
}
count++;
if(count > 400 + 50) {
break;
}
}
wsprintf(temp, "Total %d MB\n", count * step);
MessageBox(NULL, temp, "alloc test", MB_OK);
}
無限に確保するので4500MBで終わるように少し改変してみた
これで試してみな
#include <windows.h>
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmd, int n)
{
int step = 10; //10MB
int count = 0;
char temp[20];
for (;;)
{
void *p = GlobalAlloc(GPTR, step * 1024 * 1024);
if (p == NULL)
{
break;
}
count++;
if(count > 400 + 50) {
break;
}
}
wsprintf(temp, "Total %d MB\n", count * step);
MessageBox(NULL, temp, "alloc test", MB_OK);
}
186デフォルトの名無しさん
2018/08/24(金) 04:45:01.40ID:CXKCSzYg 上のプログラムは64bitでも、32bitでもコンパイルは通るよ
187デフォルトの名無しさん
2018/08/24(金) 05:30:48.46ID:CXKCSzYg そもそもWindowsは/largeaddressaware:noを付けなくても静的データは2GBまでしか使えない
動的データだけがOSが対応してるメモリ分だけ制限なく使える
WindowsにはLinuxのgccのような-mcmodel=largeや-mcmodel=mediumのようなオプションは存在しない
/largeaddressaware:noを付けると64bitアプリでも動的メモリも含めてすべてのメモリで2GB以下までしか使えなくなる
PGIのコンパイラのページでわかりやすく解説してあるよ
https://www.softek.co.jp/SPG/Pgi/TIPS/opt_64.html
動的データだけがOSが対応してるメモリ分だけ制限なく使える
WindowsにはLinuxのgccのような-mcmodel=largeや-mcmodel=mediumのようなオプションは存在しない
/largeaddressaware:noを付けると64bitアプリでも動的メモリも含めてすべてのメモリで2GB以下までしか使えなくなる
PGIのコンパイラのページでわかりやすく解説してあるよ
https://www.softek.co.jp/SPG/Pgi/TIPS/opt_64.html
188デフォルトの名無しさん
2018/08/24(金) 07:19:19.64ID:ZkSPfVdV189デフォルトの名無しさん
2018/08/24(金) 07:30:57.16ID:ZkSPfVdV >>182
そこだけ抜き出して、
しかも最適化してないコードで1%
こんなコードは全体の中では非常にわずかだろうし
タイムクリティカル部分であれば最適化される
実質差が無いメリットの為に絶対アドレスに依存したコードにする
時代に逆行だ
それでも逆行したければ
0〜2Gのアドレスしか割り当てられない2G限定アプリにしろ
そこだけ抜き出して、
しかも最適化してないコードで1%
こんなコードは全体の中では非常にわずかだろうし
タイムクリティカル部分であれば最適化される
実質差が無いメリットの為に絶対アドレスに依存したコードにする
時代に逆行だ
それでも逆行したければ
0〜2Gのアドレスしか割り当てられない2G限定アプリにしろ
190デフォルトの名無しさん
2018/08/24(金) 07:35:38.16ID:CXKCSzYg191デフォルトの名無しさん
2018/08/24(金) 07:38:24.94ID:ZkSPfVdV uOPキャッシュ
192デフォルトの名無しさん
2018/08/24(金) 07:53:32.13ID:CXKCSzYg193デフォルトの名無しさん
2018/08/24(金) 07:59:52.52ID:568m+iHd なんか初心者スレの趣旨とずれまくりなんだけど。
コンパイラのABIが「変わった」のなら、それに合わせたのを紹介しないと。
Visual Cは64bitではインラインアセンブラも使えなくなったし、AVXやSSEは組み込み関数で大概は満足できるはずって判断されたのだろう。
今のご時世わざわざアセンブリ言語でプログラミングしたいって用途は動画のコーデックやフィルタプラグインDLL、将棋とかの思考ルーチンとかでしょ。
こういうのは2GB制限下でしか使えないコードでは困るはず。
コンパイラのABIが「変わった」のなら、それに合わせたのを紹介しないと。
Visual Cは64bitではインラインアセンブラも使えなくなったし、AVXやSSEは組み込み関数で大概は満足できるはずって判断されたのだろう。
今のご時世わざわざアセンブリ言語でプログラミングしたいって用途は動画のコーデックやフィルタプラグインDLL、将棋とかの思考ルーチンとかでしょ。
こういうのは2GB制限下でしか使えないコードでは困るはず。
194デフォルトの名無しさん
2018/08/24(金) 08:09:12.98ID:568m+iHd >>189
静的配列だとサイズが決まってるから、恐らく最適化されてポインタとオフセット(ディスプレースメント)に変換されるよね。
>実質差が無いメリットの為に絶対アドレスに依存したコードにする
>時代に逆行だ
これに同意。
静的配列だとサイズが決まってるから、恐らく最適化されてポインタとオフセット(ディスプレースメント)に変換されるよね。
>実質差が無いメリットの為に絶対アドレスに依存したコードにする
>時代に逆行だ
これに同意。
195デフォルトの名無しさん
2018/08/24(金) 12:53:22.92ID:7MrYBE0R >>192
ヒント HTT
ヒント HTT
196デフォルトの名無しさん
2018/08/24(金) 14:52:13.41ID:PMMpdZPT >>185
自分は 64BIT 用C/C++コンパイラをインストールして無いので、試せません。
link.exe に、 /largeaddressaware:no を渡した場合にのみ、
GlobalAlloc() が失敗する理由は何ですか?
ポインタが32BITになる? それとも、GlobalAlloc の関数が別のものに
入れ替わってしまう?
そのどちらでもないとしたら何が原因ですか?
自分は 64BIT 用C/C++コンパイラをインストールして無いので、試せません。
link.exe に、 /largeaddressaware:no を渡した場合にのみ、
GlobalAlloc() が失敗する理由は何ですか?
ポインタが32BITになる? それとも、GlobalAlloc の関数が別のものに
入れ替わってしまう?
そのどちらでもないとしたら何が原因ですか?
197デフォルトの名無しさん
2018/08/24(金) 14:54:32.88ID:PMMpdZPT >>187
>/largeaddressaware:noを付けると64bitアプリでも動的メモリも含めてすべてのメモリで2GB以下までしか使えなくなる
>PGIのコンパイラのページでわかりやすく解説してあるよ
>https://www.softek.co.jp/SPG/Pgi/TIPS/opt_64.html
リンク先のページを見たのですが、自分には、
「動的メモリの場合にも2GB以下しか使えなくなる」
という文書が見つかりませんでした。
どこに書かれているか、ご指摘いただければ幸いです。
>/largeaddressaware:noを付けると64bitアプリでも動的メモリも含めてすべてのメモリで2GB以下までしか使えなくなる
>PGIのコンパイラのページでわかりやすく解説してあるよ
>https://www.softek.co.jp/SPG/Pgi/TIPS/opt_64.html
リンク先のページを見たのですが、自分には、
「動的メモリの場合にも2GB以下しか使えなくなる」
という文書が見つかりませんでした。
どこに書かれているか、ご指摘いただければ幸いです。
198デフォルトの名無しさん
2018/08/24(金) 16:51:48.72ID:VlbdtNmU 実験したけど2GBまでだったよ
malloc
アドレスは32bitで保持出来る
32bitアプリからの移植用だろうね
malloc
アドレスは32bitで保持出来る
32bitアプリからの移植用だろうね
199デフォルトの名無しさん
2018/08/24(金) 16:55:58.09ID:VlbdtNmU200デフォルトの名無しさん
2018/08/24(金) 17:07:40.76ID:PMMpdZPT >>199
リンカオプションによって、API の挙動まで変わってしまうんでしょうか。
そして、Win64 API の GlobalAlloc() などが返す値が 31 BIT までに
なるので、malloc() もそれにつられて、勝手に 31BIT までになると?
64BIT COFF だと、COFF Image に、/largeaddressaware:no かどうか
を示す BIT か何かが追加された???
リンカオプションによって、API の挙動まで変わってしまうんでしょうか。
そして、Win64 API の GlobalAlloc() などが返す値が 31 BIT までに
なるので、malloc() もそれにつられて、勝手に 31BIT までになると?
64BIT COFF だと、COFF Image に、/largeaddressaware:no かどうか
を示す BIT か何かが追加された???
201デフォルトの名無しさん
2018/08/24(金) 19:11:45.47ID:5OB8VNk6 >>196
無料のVisual Studio Expressでも2013以降は64bitのビルドにも対応してるよ
64bitのWindowsプログラミングに興味があるなら入れてみれば?
プログラムのコードを見ればわかるように
10MBずつメモリを確保していき
メモリが確保できなくてGlobalAllocの戻り値にNULLが返るか
確保したメモリが4500MBを越えたらbreakでループを抜けて
確保したメモリ容量を表示して終了するようになってる
で、/largeaddressaware:noを指定すると
俺の環境では1970MB確保したところでループを抜けて終了してる
つまり、1970MB確保したところで、
次にGlobalAllocを実行するとメモリが確保できなくてNULLが返る
これは、動的メモリも2GB以下しか確保できないということを示してる
/largeaddressaware:noを指定せずにコンパイルすると
4510MBまで確保して終了する
無料のVisual Studio Expressでも2013以降は64bitのビルドにも対応してるよ
64bitのWindowsプログラミングに興味があるなら入れてみれば?
プログラムのコードを見ればわかるように
10MBずつメモリを確保していき
メモリが確保できなくてGlobalAllocの戻り値にNULLが返るか
確保したメモリが4500MBを越えたらbreakでループを抜けて
確保したメモリ容量を表示して終了するようになってる
で、/largeaddressaware:noを指定すると
俺の環境では1970MB確保したところでループを抜けて終了してる
つまり、1970MB確保したところで、
次にGlobalAllocを実行するとメモリが確保できなくてNULLが返る
これは、動的メモリも2GB以下しか確保できないということを示してる
/largeaddressaware:noを指定せずにコンパイルすると
4510MBまで確保して終了する
202デフォルトの名無しさん
2018/08/24(金) 19:16:32.91ID:5OB8VNk6 >>200
Visual Studioに入ってるdumpbin.exeでコマンドプロンプトで
dumpbin /headers hogehoge.exe
とやると/largeaddressawareを指定した状態(/largeaddressaware:noを指定しない状態)だと
FILE HEADER VALUESの項目とのところに
Application can handle large (>2GB) addresses
これが表示される
なので詳しくは知らないが実行ファイルの中に/lageaddressawareの指定をする部分があるはず
これまたVisual Studioに入ってるeditbin.exeを使うと
実行ファイルそのものに/largeaddressawareや/lageaddressaware:noの指定ができる
LAAを有効にするには
editbin /lageaddressaware hogehoge.exe
LAAを無効にするには
editbin /lageaddressaware:no hogehoge.exe
Visual Studioに入ってるdumpbin.exeでコマンドプロンプトで
dumpbin /headers hogehoge.exe
とやると/largeaddressawareを指定した状態(/largeaddressaware:noを指定しない状態)だと
FILE HEADER VALUESの項目とのところに
Application can handle large (>2GB) addresses
これが表示される
なので詳しくは知らないが実行ファイルの中に/lageaddressawareの指定をする部分があるはず
これまたVisual Studioに入ってるeditbin.exeを使うと
実行ファイルそのものに/largeaddressawareや/lageaddressaware:noの指定ができる
LAAを有効にするには
editbin /lageaddressaware hogehoge.exe
LAAを無効にするには
editbin /lageaddressaware:no hogehoge.exe
203デフォルトの名無しさん
2018/08/24(金) 19:47:12.65ID:568m+iHd VCで64bitの静的配列にアクセスするコードを調べてみた。
#include <math.h>
volatile char str[1024];
volatile char c;
main(int argc, char *argv[])
{
int idx;
idx = (int)(rand() * 1024);
c = str[idx];
}
これの配列アクセス部分が
; 11 : c = str[idx];
0001c 48 63 44 24 20 movsxd rax, DWORD PTR idx$[rsp]
00021 48 8d 0d 00 00
00 00 lea rcx, OFFSET FLAT:str
00028 0f b6 04 01 movzx eax, BYTE PTR [rcx+rax]
0002c 88 05 00 00 00
00 mov BYTE PTR c, al
00028は[rcx+rax]で配列アクセスしてる
そして、00021と0002cはrip相対アドレッシングだよね?(エンコードは自信ないので)
#include <math.h>
volatile char str[1024];
volatile char c;
main(int argc, char *argv[])
{
int idx;
idx = (int)(rand() * 1024);
c = str[idx];
}
これの配列アクセス部分が
; 11 : c = str[idx];
0001c 48 63 44 24 20 movsxd rax, DWORD PTR idx$[rsp]
00021 48 8d 0d 00 00
00 00 lea rcx, OFFSET FLAT:str
00028 0f b6 04 01 movzx eax, BYTE PTR [rcx+rax]
0002c 88 05 00 00 00
00 mov BYTE PTR c, al
00028は[rcx+rax]で配列アクセスしてる
そして、00021と0002cはrip相対アドレッシングだよね?(エンコードは自信ないので)
204デフォルトの名無しさん
2018/08/24(金) 19:58:50.48ID:568m+iHd >>198
時々ポインタをDWORDに変換して構造体に突っ込んでたりすることがあるからね。
argeaddressawareは、こういうコードが含まれたアプリをどうしても64bitで動かさなきゃいけなくなった時とかに仕方なく使うオプションでしょう。
でないと、GlobalAlloc()が大きなアドレス返したら動かなくなるし。
時々ポインタをDWORDに変換して構造体に突っ込んでたりすることがあるからね。
argeaddressawareは、こういうコードが含まれたアプリをどうしても64bitで動かさなきゃいけなくなった時とかに仕方なく使うオプションでしょう。
でないと、GlobalAlloc()が大きなアドレス返したら動かなくなるし。
205デフォルトの名無しさん
2018/08/24(金) 20:08:42.11ID:568m+iHd >>200
プロセスを起動する時にexeのLAAフラグを見てメモリとかハンドルを返すAPIが32bitに収まる値を返すように設定されるんだと思う。
こういうのはプロセスごとに32bitとかにも切り替えられる(この場合はシステムDLLは64bitとは別だけど)ので、
互換性を確保する仕組みが裏で動いてるはずだよ。
プロセスを起動する時にexeのLAAフラグを見てメモリとかハンドルを返すAPIが32bitに収まる値を返すように設定されるんだと思う。
こういうのはプロセスごとに32bitとかにも切り替えられる(この場合はシステムDLLは64bitとは別だけど)ので、
互換性を確保する仕組みが裏で動いてるはずだよ。
206デフォルトの名無しさん
2018/08/24(金) 20:18:03.36ID:568m+iHd >>203のコードバイトの折り返し部分のタブが詰められて見にくいので
0001c 48 63 44 24 20 movsxd rax, DWORD PTR idx$[rsp]
00021 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:str
00028 0f b6 04 01 movzx eax, BYTE PTR [rcx+rax]
0002c 88 05 00 00 00 00 mov BYTE PTR c, al
0001c 48 63 44 24 20 movsxd rax, DWORD PTR idx$[rsp]
00021 48 8d 0d 00 00 00 00 lea rcx, OFFSET FLAT:str
00028 0f b6 04 01 movzx eax, BYTE PTR [rcx+rax]
0002c 88 05 00 00 00 00 mov BYTE PTR c, al
207デフォルトの名無しさん
2018/08/24(金) 21:46:35.00ID:5OB8VNk6 >>203
VC++だと/FAオプションを指定するとアセンブラ出力もされるよ
ただ、64bitのVC++コンパイラが吐き出すアセンブラコードは
そのままではml64.exeでアセンブルできないけど
ml64.exeでアセンブルできるように修正できたらml64.exeでアセンブルする時に
/Flオプションを指定するとリスティングファイルを出力してくれる
VC++だと/FAオプションを指定するとアセンブラ出力もされるよ
ただ、64bitのVC++コンパイラが吐き出すアセンブラコードは
そのままではml64.exeでアセンブルできないけど
ml64.exeでアセンブルできるように修正できたらml64.exeでアセンブルする時に
/Flオプションを指定するとリスティングファイルを出力してくれる
208デフォルトの名無しさん
2018/08/24(金) 22:08:39.28ID:568m+iHd209デフォルトの名無しさん
2018/08/25(土) 04:35:15.70ID:gxBSyOuw プロセスのアドレス空間が、4GB までだから
その内、Linux では1GB、Windows では2GB を、カーネル空間に割り当てているから、
残りのユーザー空間は、3GB, 2GB になる
カーネル空間は、全プロセス共通の空間だから、各プロセスで使えないアドレス
その内、Linux では1GB、Windows では2GB を、カーネル空間に割り当てているから、
残りのユーザー空間は、3GB, 2GB になる
カーネル空間は、全プロセス共通の空間だから、各プロセスで使えないアドレス
210デフォルトの名無しさん
2018/08/25(土) 05:52:55.11ID:5KTEEpUR 64bit Windowsでの2GB制限ってのは、単にメモリ確保時のアドレスの割り当て方やハンドルの値が変わるだけで、
アクセスできない場所では普通に例外が発生するだけのこと。
/largeaddressaware:yesの状態では、32bitの範囲のアドレスがが割り当てられてないから
rip相対を使って静的変数のあるアドレスを取得するってことね。
アクセスできない場所では普通に例外が発生するだけのこと。
/largeaddressaware:yesの状態では、32bitの範囲のアドレスがが割り当てられてないから
rip相対を使って静的変数のあるアドレスを取得するってことね。
211デフォルトの名無しさん
2018/08/25(土) 05:57:44.86ID:5KTEEpUR 割り当てられてないってのは変だったね。
アクセス権限が与えられてないからってこと。
アクセス権限が与えられてないからってこと。
212デフォルトの名無しさん
2018/08/25(土) 11:07:20.24ID:auNeFg4G 偉そうなもんだな。
もうちょっと、言い方ってもんを学んだ方がいい。
人間性に問題あるかも。
もうちょっと、言い方ってもんを学んだ方がいい。
人間性に問題あるかも。
213デフォルトの名無しさん
2018/09/03(月) 04:21:34.86ID:A+X9ST7o アセンブラの命令を覚えたいのと
デバッガーを使いこなしたいんですが
何かお勧めの勉強方法はありますか?
C入門程度だけの知識だけでアセンブラは全く知りません
よろしくお願い致します
デバッガーを使いこなしたいんですが
何かお勧めの勉強方法はありますか?
C入門程度だけの知識だけでアセンブラは全く知りません
よろしくお願い致します
214デフォルトの名無しさん
2018/09/03(月) 11:24:23.57ID:dhYkuZhG CPUは何?
215デフォルトの名無しさん
2018/09/03(月) 12:38:16.62ID:f+M/nyW5 書いてないってことは決まって無いんだろう
Visual Studio Community 2017
x86 64bit
ml64.exe
が環境としては一番簡単かな
何もしない関数をアセンブラで作って
Cからその関数を呼ぶところから始めよう
Visual Studio Community 2017
x86 64bit
ml64.exe
が環境としては一番簡単かな
何もしない関数をアセンブラで作って
Cからその関数を呼ぶところから始めよう
216デフォルトの名無しさん
2018/09/03(月) 20:27:11.25ID:A+X9ST7o os10 64bitです
C++でアセンブラ使えるんですね
知りませんでした。そこら辺も調べてみます
デバッガーでコードを読んで書き換えられるようになりたいです
C++でアセンブラ使えるんですね
知りませんでした。そこら辺も調べてみます
デバッガーでコードを読んで書き換えられるようになりたいです
217デフォルトの名無しさん
2018/09/03(月) 20:36:15.47ID:i7qE7EE1 マカーか
218デフォルトの名無しさん
2018/09/04(火) 16:50:20.52ID:ErgP6cOz 横からだけど、
それに必要なのはバイナリからアセンブラコードを出力する逆アセンブラじゃないの?
それとも基礎知識として習得したいってことなのか
それに必要なのはバイナリからアセンブラコードを出力する逆アセンブラじゃないの?
それとも基礎知識として習得したいってことなのか
219デフォルトの名無しさん
2018/09/04(火) 17:01:04.80ID:hMkkrsf+ チートしたい!
220デフォルトの名無しさん
2018/09/04(火) 22:32:50.81ID:snmgssEj >>218
これから勉強するって段階で逆アセはまだ早い。まずCで簡単なコード書いてアセンブラソース出力
それを見て少しずつ変更して動作を勉強。どきどき暴走させて遊ぶのがいい。
Cやアセンブラのソースがないバイナリを逆アセしても、逆アセはコードとデータの区別なしにコード化するから混乱する。
これから勉強するって段階で逆アセはまだ早い。まずCで簡単なコード書いてアセンブラソース出力
それを見て少しずつ変更して動作を勉強。どきどき暴走させて遊ぶのがいい。
Cやアセンブラのソースがないバイナリを逆アセしても、逆アセはコードとデータの区別なしにコード化するから混乱する。
221デフォルトの名無しさん
2018/09/04(火) 22:50:42.54ID:bj+tb6HS 回答ありがとうございます;
アセンブラの実行環境整える(実機だのエミュだの)用意するのが物凄い敷居高そうに感じるので
チートエンジンやollydbg?ってやつでオフライン用のゲームでも解析しながら
アセンブラ命令群を覚えようと思ってます。
アセンブラの命令を覚えるのだけなら後者でも力つきますかね?目標はウイルスのデバッグとか出来るようになりたいです
アセンブラの実行環境整える(実機だのエミュだの)用意するのが物凄い敷居高そうに感じるので
チートエンジンやollydbg?ってやつでオフライン用のゲームでも解析しながら
アセンブラ命令群を覚えようと思ってます。
アセンブラの命令を覚えるのだけなら後者でも力つきますかね?目標はウイルスのデバッグとか出来るようになりたいです
222デフォルトの名無しさん
2018/09/05(水) 01:22:32.69ID:vQx16S6k >>221
>目標はウイルスのデバッグとか出来るようになりたいです
どうしてそう反社会的な方ばっかり目がいくんだい。
これだから、ハッカー=クラッカー、悪者、のイメージが付く。
昔は、アセンブラといえば、速さのために学んだものなのに。
君みたいなのにはプログラムになんか興味を持たないで欲しい。
>目標はウイルスのデバッグとか出来るようになりたいです
どうしてそう反社会的な方ばっかり目がいくんだい。
これだから、ハッカー=クラッカー、悪者、のイメージが付く。
昔は、アセンブラといえば、速さのために学んだものなのに。
君みたいなのにはプログラムになんか興味を持たないで欲しい。
223デフォルトの名無しさん
2018/09/05(水) 02:37:54.86ID:wyXCwUhn >>どうしてそう反社会的な方ばっかり目がいくんだい。
そう…ではなくてですね
将来ウイルスとかランサムウェアの対策ツールとか作ってみたいから
デバッグスキル付けたいと思って、覚えたいと思いました。
http://www5c.biglobe.ne.jp/~ecb/assembler/assembler00.html 見て実行環境頑張って作って覚えようと思ったんですけど
とっつきづらすぎると思って;
てかVisualStudioって自分のコードアセンブラで出力したり出来るんですね
全然知りませんでした。ありがとうございます
そう…ではなくてですね
将来ウイルスとかランサムウェアの対策ツールとか作ってみたいから
デバッグスキル付けたいと思って、覚えたいと思いました。
http://www5c.biglobe.ne.jp/~ecb/assembler/assembler00.html 見て実行環境頑張って作って覚えようと思ったんですけど
とっつきづらすぎると思って;
てかVisualStudioって自分のコードアセンブラで出力したり出来るんですね
全然知りませんでした。ありがとうございます
224デフォルトの名無しさん
2018/09/05(水) 03:52:48.57ID:EatH13os ウィルスってね、勉強のつもりで作っても、いざ出来上がると使ってみたくなるもんなんだよね。
そういう誘惑に勝てるかどうか
そういう誘惑に勝てるかどうか
225デフォルトの名無しさん
2018/09/05(水) 06:27:13.70ID:wyXCwUhn >>224
そういう方もいらっしゃるんですね。
プログラミング歴はもといパソコンも初心者レベルにしかない自分には縁のない響きですね・・
ところでC++のコードをvisualstudioでアセンブラ出力とはどうやるんでしょうか?
気になって調べてみたんですが デバック(D)→ウィンドウ→アセンブラ っと進むと出てくると書いてあるんですが
そんな項目ありません;
そういう方もいらっしゃるんですね。
プログラミング歴はもといパソコンも初心者レベルにしかない自分には縁のない響きですね・・
ところでC++のコードをvisualstudioでアセンブラ出力とはどうやるんでしょうか?
気になって調べてみたんですが デバック(D)→ウィンドウ→アセンブラ っと進むと出てくると書いてあるんですが
そんな項目ありません;
226デフォルトの名無しさん
2018/09/05(水) 11:13:33.31ID:/V9AsOwQ debug.exe
debug64.exe
debug64.exe
227デフォルトの名無しさん
2018/09/05(水) 11:34:16.13ID:TWmx8fnR OllyDbg とか、
うさぴょんの「うさみみハリケーン・スペシャルねこまんま」とか、
将棋AI「やねうら王」の作者、やねうらおの本「解析魔法少女 美咲ちゃん」とか
デバッガによるx86プログラム解析入門 【x64対応版】、うさぴょん、2014
うさぴょんの「うさみみハリケーン・スペシャルねこまんま」とか、
将棋AI「やねうら王」の作者、やねうらおの本「解析魔法少女 美咲ちゃん」とか
デバッガによるx86プログラム解析入門 【x64対応版】、うさぴょん、2014
228デフォルトの名無しさん
2018/09/05(水) 11:55:15.09ID:gDSR0MtA229デフォルトの名無しさん
2018/09/05(水) 20:44:59.69ID:wyXCwUhn >>227-228
ありがとうございます
ソリューション周辺探しましたが https://gyazo.com/b58d77fd28f08e941c91b337938d1f6c
無かったです……
VSインストールする時2つくらいしか選択しなかったんですがそれがまずかったんでしょうか
ollydbgというのも調べてみます
ありがとうございます
ソリューション周辺探しましたが https://gyazo.com/b58d77fd28f08e941c91b337938d1f6c
無かったです……
VSインストールする時2つくらいしか選択しなかったんですがそれがまずかったんでしょうか
ollydbgというのも調べてみます
230デフォルトの名無しさん
2018/09/06(木) 01:20:57.16ID:UZSBUUik VSでC/C++のデバッギングに入ってステップインしてたらアセンブラのコードが出てこないか?
231デフォルトの名無しさん
2018/09/06(木) 01:24:39.50ID:uY3Jh6lT >>229
C/C++の所のツリー開け
C/C++の所のツリー開け
232デフォルトの名無しさん
2018/09/06(木) 05:22:06.40ID:psScFFtw Cならインラインアセンブラ使えば良いんでない?
233デフォルトの名無しさん
2018/09/06(木) 14:49:24.96ID:jOmc1UUP いや、普通にターゲットCPUのニーモニック表を探して来て見ろよ
234デフォルトの名無しさん
2018/09/24(月) 01:13:48.37ID:rSek34EX 取り敢えずアセンブラ上の数字2進数(或いは16進数)を桁ごとに分けて十進数にして、+30して(文字コードに変換)する事には成功した。
何進数か関係無く、10の位なら10ずつ、100の位なら100ずつ引いて実現。
筆算のアルゴリズムだともっと速いらしいので、時間があれば挑戦したい。
時間があれば。。。
何進数か関係無く、10の位なら10ずつ、100の位なら100ずつ引いて実現。
筆算のアルゴリズムだともっと速いらしいので、時間があれば挑戦したい。
時間があれば。。。
235デフォルトの名無しさん
2018/09/24(月) 01:17:43.11ID:rSek34EX x 何進数か関係無く、10の位なら10ずつ、100の位なら100ずつ引いて
o 何進数か関係無く、(何進数の10でも10進数の10だと言うことは変わらないので)10の位なら10(16進数だとA)ずつ、100の位なら100ずつ引いて
o 何進数か関係無く、(何進数の10でも10進数の10だと言うことは変わらないので)10の位なら10(16進数だとA)ずつ、100の位なら100ずつ引いて
236デフォルトの名無しさん
2018/09/25(火) 01:58:20.74ID:4rHiZGxF 8bitISAの経験はあるんだがIA32やAMD64のプログラミングマニュアルを見ると命令の多さにめまいがする
しかもググってみるとメモリアドレッシングもなにやら作法があるようでよくわからん・・・
な状態なのだがIA32/AMD64のアセンブラを勉強するのにおすすめの資料とかあるかな
今のところ自力で書いたことのあるISAは78K0S、8051、AVR。基本的な概念はわかっているつもり
リンカ周りは不安あり。プラットフォームはWindowsかLinuxかFreeBSDを検討中
しかもググってみるとメモリアドレッシングもなにやら作法があるようでよくわからん・・・
な状態なのだがIA32/AMD64のアセンブラを勉強するのにおすすめの資料とかあるかな
今のところ自力で書いたことのあるISAは78K0S、8051、AVR。基本的な概念はわかっているつもり
リンカ周りは不安あり。プラットフォームはWindowsかLinuxかFreeBSDを検討中
237デフォルトの名無しさん
2018/09/25(火) 08:56:01.40ID:oRUMH9qn >>236
ISAって何のこと?
ISAって何のこと?
238デフォルトの名無しさん
2018/09/25(火) 09:25:52.53ID:oRUMH9qn ISA=instruction set architecture=命令セットアーキテクチャ
や、
ISA=PC/ATの拡張スロットのバス仕様
??
や、
ISA=PC/ATの拡張スロットのバス仕様
??
239デフォルトの名無しさん
2018/09/25(火) 18:37:53.38ID:oPuX37oa このスレでISAをIndustry Standard Architectureと解釈する必要ってあるのか?
240デフォルトの名無しさん
2018/09/26(水) 04:10:17.53ID:GMLyVXjl 誤解を生まないよう書き込む際は気を付けた方がいいね
241デフォルトの名無しさん
2018/09/26(水) 10:35:31.91ID:s/2dxbJy >>236
VCのx64はインラインアセンブラも使えなくなってるんだから、特殊なビット操作やりたいのでなければ
組み込み関数覚えてからの方が楽なんじゃないの
https://software.intel.com/sites/landingpage/IntrinsicsGuide/
右端に対応するニーモニックが書いてある
VCのx64はインラインアセンブラも使えなくなってるんだから、特殊なビット操作やりたいのでなければ
組み込み関数覚えてからの方が楽なんじゃないの
https://software.intel.com/sites/landingpage/IntrinsicsGuide/
右端に対応するニーモニックが書いてある
242デフォルトの名無しさん
2018/09/27(木) 10:28:07.85ID:+X2PETpr >>240
アスペじゃなければこの文脈でそれはない
アスペじゃなければこの文脈でそれはない
243デフォルトの名無しさん
2018/09/27(木) 10:47:26.07ID:JRG0evD8 そもそも8bitISAなんて言い方は一般的ではないもん。
244デフォルトの名無しさん
2018/09/27(木) 10:58:42.91ID:JRG0evD8 かなりアセンブラ経験あるけど、8bit ISAと聞いても意味が分からなかった。
多分、8bit CPUとか、8bit マイコンのことが言いたかったのではないかとは
思ったけど、意味がはっきりしなかったので念のため聞いてみた。
個人的には、Instrucstion Set Architectureの意味での「ISA」という
言い方は、Intelのマニュアルなどで最近目にするようになった印象が
ある言い方。
修正に告ぐ修正を重ねてが複雑化したx86系CPUのあの複雑さのニュアンス
を出すためにIntelが使い始めた言葉かもしれない。
昔、Z80が流行っていたころは、日本の雑誌などでは、8bit CPUと言われて
いたし、炊飯器や冷蔵庫では、今でもCPUよりもどちらかというと
I/OポートやA/Dコンバーターを内蔵しているみたいななニュアンスを
含めて「マイコン」と言われていると思う。
ISAという言葉は、Intelマニュアル以外ではあまり見たことない。
多分、8bit CPUとか、8bit マイコンのことが言いたかったのではないかとは
思ったけど、意味がはっきりしなかったので念のため聞いてみた。
個人的には、Instrucstion Set Architectureの意味での「ISA」という
言い方は、Intelのマニュアルなどで最近目にするようになった印象が
ある言い方。
修正に告ぐ修正を重ねてが複雑化したx86系CPUのあの複雑さのニュアンス
を出すためにIntelが使い始めた言葉かもしれない。
昔、Z80が流行っていたころは、日本の雑誌などでは、8bit CPUと言われて
いたし、炊飯器や冷蔵庫では、今でもCPUよりもどちらかというと
I/OポートやA/Dコンバーターを内蔵しているみたいななニュアンスを
含めて「マイコン」と言われていると思う。
ISAという言葉は、Intelマニュアル以外ではあまり見たことない。
245デフォルトの名無しさん
2018/09/27(木) 11:23:55.29ID:tmnyfQyv ARM でも MIPS でも普通に ISA 使うけど。
8bit の頃は、セカンドソースはあっても、ISA レベルでのライセンシングが無いか稀だったんじゃないかなあ。
どっちにしろ、16bit バスの ISA を思いつくのはちょっと理解できない。
8bit の頃は、セカンドソースはあっても、ISA レベルでのライセンシングが無いか稀だったんじゃないかなあ。
どっちにしろ、16bit バスの ISA を思いつくのはちょっと理解できない。
246デフォルトの名無しさん
2018/09/27(木) 11:29:57.13ID:JRG0evD8247デフォルトの名無しさん
2018/09/27(木) 11:40:30.81ID:JRG0evD8 >>245
「8-bit ISA card」
で検索すると、色々出てくる。
当時、愛器はNEC製だったのでPC/ATのバス規格であったところのISA
については知らなかったけど。
コンピュータは用語が多様なので、省略形は注意が必要だと思う。
ガングロ女子高生が省略後で通じ合えるのは、多分、興味の対象が
狭いか、語彙が少ないからこそかもしれないと思ってる。
語彙が豊富な人ほど、略さずそのまま言う傾向があると思うし。
「8-bit ISA card」
で検索すると、色々出てくる。
当時、愛器はNEC製だったのでPC/ATのバス規格であったところのISA
については知らなかったけど。
コンピュータは用語が多様なので、省略形は注意が必要だと思う。
ガングロ女子高生が省略後で通じ合えるのは、多分、興味の対象が
狭いか、語彙が少ないからこそかもしれないと思ってる。
語彙が豊富な人ほど、略さずそのまま言う傾向があると思うし。
248デフォルトの名無しさん
2018/09/27(木) 11:40:33.72ID:tmnyfQyv249デフォルトの名無しさん
2018/09/27(木) 11:49:44.12ID:JRG0evD8250デフォルトの名無しさん
2018/09/27(木) 11:55:04.47ID:JRG0evD8 アセンブラの基礎が分かっている人なら、Intelの3 Volumeがセットになった
英文マニュアルがお勧め(なお、英語が分かる人は、日本語版は読まない
方がいいと思う。混乱の元になるから。英語が分からない人は、多分、
混乱しながら時間をかけて前後関係から推定して理解することになる。)
ModRMについても書いてある。ただし、32BITのものが詳しく書かれていて、
64BITのものについては、補足のように後から書かれている。
REX prefixとかと関連して。
非常に壮大なマニュアルで、忘れたけど、総ページ数は5,000ページくらい
あったかもしれないけど、必要なところをかいつまんで読めばいい。
アセンブラ経験がある人なら読めるはず。
英文マニュアルがお勧め(なお、英語が分かる人は、日本語版は読まない
方がいいと思う。混乱の元になるから。英語が分からない人は、多分、
混乱しながら時間をかけて前後関係から推定して理解することになる。)
ModRMについても書いてある。ただし、32BITのものが詳しく書かれていて、
64BITのものについては、補足のように後から書かれている。
REX prefixとかと関連して。
非常に壮大なマニュアルで、忘れたけど、総ページ数は5,000ページくらい
あったかもしれないけど、必要なところをかいつまんで読めばいい。
アセンブラ経験がある人なら読めるはず。
251デフォルトの名無しさん
2018/09/27(木) 12:02:53.61ID:yf1/OigC みんなここを読んでいるのが自分と同じ業界の専門家だと思っているのかな?
初心者スレなんだから上級者は来るなよ
初心者スレなんだから上級者は来るなよ
252デフォルトの名無しさん
2018/09/27(木) 12:09:02.87ID:JRG0evD8 >>250
PDFファイルは、Adobe純正のものではなく、SumatraPDFがお勧め。
場合によっては、それと、PDF-XChange Viewerとの両使いも便利。
2つのビューアーがあると、同じファイルの異なるページを同時に
見ることが出来る。
特に、SumatraPDFは、ネットブラウザやWindows用の
テキスト・エディタなどとよく似た使い勝手で便利。
PDFファイルは、Adobe純正のものではなく、SumatraPDFがお勧め。
場合によっては、それと、PDF-XChange Viewerとの両使いも便利。
2つのビューアーがあると、同じファイルの異なるページを同時に
見ることが出来る。
特に、SumatraPDFは、ネットブラウザやWindows用の
テキスト・エディタなどとよく似た使い勝手で便利。
253デフォルトの名無しさん
2018/09/27(木) 12:29:35.23ID:nUEopGTJ254デフォルトの名無しさん
2018/09/27(木) 12:30:49.36ID:lrUHFZkm 自分の知識不足を棚に上げて絡む馬鹿アスペ
255デフォルトの名無しさん
2018/09/27(木) 12:34:10.71ID:JRG0evD8 お互いに知識に偏りがあるからしょうがないんだよ。
だから、分からない言葉があれば言葉の確認が必要となると思う。
名プログラマやIQ170の人でも、知らない分野では知識不足はあるよ。
だから、分からない言葉があれば言葉の確認が必要となると思う。
名プログラマやIQ170の人でも、知らない分野では知識不足はあるよ。
256デフォルトの名無しさん
2018/09/27(木) 12:51:27.68ID:BciEc+9A >>255
うん、78K0S、8051、AVRがなじみの無いCPUと聞いてショックを受けている。
うん、78K0S、8051、AVRがなじみの無いCPUと聞いてショックを受けている。
257デフォルトの名無しさん
2018/09/27(木) 12:59:24.22ID:JRG0evD8 >>256
78K0Sが、NEC製のマイコンだということだけは、昔知ったことがある。
でも、昔といってもとても最近。
8051は、PC-8801のシリアルコントローラに、似たような型番のものがあったような
気がしたが、たぶん関係ないけど、正確な型番は思い出せない。
78K0Sが、NEC製のマイコンだということだけは、昔知ったことがある。
でも、昔といってもとても最近。
8051は、PC-8801のシリアルコントローラに、似たような型番のものがあったような
気がしたが、たぶん関係ないけど、正確な型番は思い出せない。
258デフォルトの名無しさん
2018/09/27(木) 13:05:15.67ID:JRG0evD8259デフォルトの名無しさん
2018/09/27(木) 16:23:11.07ID:JRG0evD8 >>236
命令が多いのは、基本的には、MMX, SSE〜SSE4, AVX, AVX2, AVX512 が
追加されたことが大きい。その辺の命令はまずは、無視。
整数命令(汎用命令)から見るといい。
なおその前に、どんなレジスタがあるかについて勉強する。
「basic execution environment」みたいな節に書いてある。
レジスタは拡張につぐ拡張があったので、理解するのにそれなりの時間がかかる。
アルファベットごとの命令表の、mov, add, sub, mul, div, imul, idiv,
push, pop, call, jmp, jcc 系を中心に見た後、ModRMについて書かれた節を見る。
最初は、16BIT/32BIT の ModRM、SIB について理解する。
その際、operand prefix, address prefix について理解する。
その後、64BIT の long mode, compatible mode の説明を読んだ後、
64BIT の ModRM, SIB について、REX prefix とまとめて理解する。
ちなみに、以下は後回しにする:
fadd, fsub, fmul, fdiv, fldp, fld, fstp, fld は、x87 FPU。
padd, psub は、MMX, addps, addss, subps, subss, mulps, mulss は、SSE系。
mm0〜mm7, xmm, ymm, zmm, に関する movxxxx も最初は無視。
これらの movxxxx は、アルファベット順の命令ごとについての書かれた章
のに解説が書かれているが、アラインだとかの説明が難しい。
実は、同じマニュアルセットの全然別の場所にこれらの movxxxx 命令の
説明が割りと平易な言葉で書かれているので参考になる。ただし、英語。
翻訳版の日本語だと余計に意味が分からないかもしれないの注意。
AVX系命令は、まず、VEX, EVEX prefix を読む。REX prefix が完全に理解
してないと理解は難しいと思う。
命令が多いのは、基本的には、MMX, SSE〜SSE4, AVX, AVX2, AVX512 が
追加されたことが大きい。その辺の命令はまずは、無視。
整数命令(汎用命令)から見るといい。
なおその前に、どんなレジスタがあるかについて勉強する。
「basic execution environment」みたいな節に書いてある。
レジスタは拡張につぐ拡張があったので、理解するのにそれなりの時間がかかる。
アルファベットごとの命令表の、mov, add, sub, mul, div, imul, idiv,
push, pop, call, jmp, jcc 系を中心に見た後、ModRMについて書かれた節を見る。
最初は、16BIT/32BIT の ModRM、SIB について理解する。
その際、operand prefix, address prefix について理解する。
その後、64BIT の long mode, compatible mode の説明を読んだ後、
64BIT の ModRM, SIB について、REX prefix とまとめて理解する。
ちなみに、以下は後回しにする:
fadd, fsub, fmul, fdiv, fldp, fld, fstp, fld は、x87 FPU。
padd, psub は、MMX, addps, addss, subps, subss, mulps, mulss は、SSE系。
mm0〜mm7, xmm, ymm, zmm, に関する movxxxx も最初は無視。
これらの movxxxx は、アルファベット順の命令ごとについての書かれた章
のに解説が書かれているが、アラインだとかの説明が難しい。
実は、同じマニュアルセットの全然別の場所にこれらの movxxxx 命令の
説明が割りと平易な言葉で書かれているので参考になる。ただし、英語。
翻訳版の日本語だと余計に意味が分からないかもしれないの注意。
AVX系命令は、まず、VEX, EVEX prefix を読む。REX prefix が完全に理解
してないと理解は難しいと思う。
260デフォルトの名無しさん
2018/09/27(木) 16:33:04.36ID:JRG0evD8 >>259
ちなみに、命令表は、
1. マニュアルの中心付近にアルファベット順に書かれているもの
2. ずっと後の付録の当たりに確か2進数の BIT 的に書かれているもの
3. マシン語から命令へ逆にたどれるもの
の3種類ある。
以上の命令表のうち、最初に読むべきなのは、上記の「1」のもの。
その命令表を見るための準備も必要。
マニュアルをよく探すと、/0〜/7 の意味、+b, +w, +d, +q の意味などが書かれた
部分がある。基本的には、そこを読まないとちゃんとした理解は出来ない。
それだけでなく、命令表も2部に分かれているような独特の読み方がある。それも、
上記の説明と同じような場所にまとめて出ている(分かりにくいが)。
(オペランドの種類を1つの表では表しにくいので、ポインタ参照のような感じで
記号で、後の表の行を指定するような感じになっている。)
REX prefixについては、AMD社のAMD64のManualも当然参考になる。
REX prefix は、色々と注意が必要で、細かい点を正確に理解するのは
しばらく時間がかかる。
ちなみに、命令表は、
1. マニュアルの中心付近にアルファベット順に書かれているもの
2. ずっと後の付録の当たりに確か2進数の BIT 的に書かれているもの
3. マシン語から命令へ逆にたどれるもの
の3種類ある。
以上の命令表のうち、最初に読むべきなのは、上記の「1」のもの。
その命令表を見るための準備も必要。
マニュアルをよく探すと、/0〜/7 の意味、+b, +w, +d, +q の意味などが書かれた
部分がある。基本的には、そこを読まないとちゃんとした理解は出来ない。
それだけでなく、命令表も2部に分かれているような独特の読み方がある。それも、
上記の説明と同じような場所にまとめて出ている(分かりにくいが)。
(オペランドの種類を1つの表では表しにくいので、ポインタ参照のような感じで
記号で、後の表の行を指定するような感じになっている。)
REX prefixについては、AMD社のAMD64のManualも当然参考になる。
REX prefix は、色々と注意が必要で、細かい点を正確に理解するのは
しばらく時間がかかる。
261デフォルトの名無しさん
2018/09/27(木) 16:36:18.33ID:qYKYy6B3 墓場に一番近いスレ
262デフォルトの名無しさん
2018/09/27(木) 16:49:13.96ID:JRG0evD8 >>260
分かっているかもしれないが、x86系では、if()文に相当するものは、
基本的には、cmp aaa,bbb 命令で、(仮想的に)引き算をした後、
結果に基づいて、
zf, cf, sf, of(zero flag, carry flag, sign flag, overflow flag) など
のフラグ類に値が設定されて、そのあと、フラグ類に基づいて、
jz, jnz, jg, jge, jl, jle, ja, jae, jb, jbe などで jump (branch) する仕組み。
cmp命令は、ほとんど sub と同じだが、sub は、結果を destination
に実際に代入するのに対し、cmpは、結果はフラグ類以外にはどこにも
返さない。
subでも、フラグ類は設定されるので、上記の条件ジャンプは cmpと
全く同様に使える。実は、add や test, and, xor などでも、
条件ジャンプは行える場合がある。
整数で多倍長の加算を行うには、caryy flag を使って、add, adc を続けて行う。
減算の場合は、sub, sbb。
add ・・・
adc ・・・
adc ・・・
adc ・・・
・・・
みたいにすると、どれだけでも桁数は増やせる。
掛け算や、割り算の多倍長計算については、もっと数学的に行うが足し算と
引き算だけは、簡単に行える。
分かっているかもしれないが、x86系では、if()文に相当するものは、
基本的には、cmp aaa,bbb 命令で、(仮想的に)引き算をした後、
結果に基づいて、
zf, cf, sf, of(zero flag, carry flag, sign flag, overflow flag) など
のフラグ類に値が設定されて、そのあと、フラグ類に基づいて、
jz, jnz, jg, jge, jl, jle, ja, jae, jb, jbe などで jump (branch) する仕組み。
cmp命令は、ほとんど sub と同じだが、sub は、結果を destination
に実際に代入するのに対し、cmpは、結果はフラグ類以外にはどこにも
返さない。
subでも、フラグ類は設定されるので、上記の条件ジャンプは cmpと
全く同様に使える。実は、add や test, and, xor などでも、
条件ジャンプは行える場合がある。
整数で多倍長の加算を行うには、caryy flag を使って、add, adc を続けて行う。
減算の場合は、sub, sbb。
add ・・・
adc ・・・
adc ・・・
adc ・・・
・・・
みたいにすると、どれだけでも桁数は増やせる。
掛け算や、割り算の多倍長計算については、もっと数学的に行うが足し算と
引き算だけは、簡単に行える。
263デフォルトの名無しさん
2018/09/27(木) 17:57:17.06ID:ry/jwNzc264デフォルトの名無しさん
2018/09/27(木) 19:29:19.93ID:fZkL81UT まずはCコンパイラにアセンブラ出力させて、
それを元に命令の動作をリファレンスマニュアルで確認していった方が楽なのでは?
いきなりマニュアルだけ読むだけだと大変だろうね
ちなみにC++よりもC言語の方がアセンブラ出力を読むのは簡単なはず
あと、Visual C++なら32bitのx86でやった方がいいよ
64bitのアセンブラ出力はそのままアセンブラでアセンブルできないはず
32bitならVisual C++のアセンブラ出力をアセンブラでそのままアセンブルできる
それを元に命令の動作をリファレンスマニュアルで確認していった方が楽なのでは?
いきなりマニュアルだけ読むだけだと大変だろうね
ちなみにC++よりもC言語の方がアセンブラ出力を読むのは簡単なはず
あと、Visual C++なら32bitのx86でやった方がいいよ
64bitのアセンブラ出力はそのままアセンブラでアセンブルできないはず
32bitならVisual C++のアセンブラ出力をアセンブラでそのままアセンブルできる
265デフォルトの名無しさん
2018/09/27(木) 19:51:12.89ID:fZkL81UT gccなら64bitでもアセンブラ出力できる
AVRを使ったことがあってgcc使ってたのならLinux上でgcc使ってみるのもあり
この場合、コマンドライン主体になるけどね
Linuxなら
objdump -M intel -d hogehoge
という感じで実行ファイルやオブジェクトファイルの逆アセンブルができる
gccでx86のアセンブラ出力をするときは-masm=intelのオプションを忘れずに
やり方はこんな感じ
gcc -S -masm=intel -o hogehoge.s hogehoge.c
このアセンブラリストを
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
とアセンブルできる
これでできたオブジェクトファイルを
gcc -o hogehoge hogehoge.o
これで実行ファイルが完成
gdbではdisasで逆アセンブルできる
逆アセンブルする前にset disassembly-flavor intelを1回入力してやれば
それ以降の逆アセンブルがintel記法で出力される
最後に、WindowsとLinuxでは関数の呼び出し規約が違ったりするのをお忘れなく
AVRを使ったことがあってgcc使ってたのならLinux上でgcc使ってみるのもあり
この場合、コマンドライン主体になるけどね
Linuxなら
objdump -M intel -d hogehoge
という感じで実行ファイルやオブジェクトファイルの逆アセンブルができる
gccでx86のアセンブラ出力をするときは-masm=intelのオプションを忘れずに
やり方はこんな感じ
gcc -S -masm=intel -o hogehoge.s hogehoge.c
このアセンブラリストを
as -a=hogehoge.lst -o hogehoge.o hogehoge.s
とアセンブルできる
これでできたオブジェクトファイルを
gcc -o hogehoge hogehoge.o
これで実行ファイルが完成
gdbではdisasで逆アセンブルできる
逆アセンブルする前にset disassembly-flavor intelを1回入力してやれば
それ以降の逆アセンブルがintel記法で出力される
最後に、WindowsとLinuxでは関数の呼び出し規約が違ったりするのをお忘れなく
266デフォルトの名無しさん
2018/09/27(木) 19:58:33.40ID:fZkL81UT gccなら上のように64bitのx86_64のアセンブラ出力もasでアセンブルできるよ
267デフォルトの名無しさん
2018/09/27(木) 20:02:31.89ID:fZkL81UT x86のアセンブラで注意が必要なのは
例えば、
mov eax, data01
とあった場合、data01のメモリの内容がeaxに入る
決してdata01のアドレスではない
data01のアドレスを読み込みたかったら
mov eax, offset data01
こうすること
例えば、
mov eax, data01
とあった場合、data01のメモリの内容がeaxに入る
決してdata01のアドレスではない
data01のアドレスを読み込みたかったら
mov eax, offset data01
こうすること
268デフォルトの名無しさん
2018/09/27(木) 23:08:23.40ID:F6rrREqm まただよ…
269デフォルトの名無しさん
2018/09/28(金) 15:40:04.81ID:O5kQkBkV lea だろう常考
270デフォルトの名無しさん
2018/09/29(土) 06:54:45.13ID:31v81hqm 32bitでは
lea eax, hogehoge
よりも
mov eax, offset hogehoge
の方が命令が1バイト少なくなる
64bitでは
lea rax, hogehoge
だとアドレスはRIP相対の32itDISPになって7バイト
mov rax, offset hogehoge
だと64bitのimmを読み込むので10バイトになって3バイト長くなるけど
lea eax, hogehoge
よりも
mov eax, offset hogehoge
の方が命令が1バイト少なくなる
64bitでは
lea rax, hogehoge
だとアドレスはRIP相対の32itDISPになって7バイト
mov rax, offset hogehoge
だと64bitのimmを読み込むので10バイトになって3バイト長くなるけど
271デフォルトの名無しさん
2018/09/29(土) 07:01:44.57ID:31v81hqm gccやgasだとx86_64で64bit immを読み込む命令のニーモニックが違うんだよな
movabs rax, offset flat hogehoge
gasだとこうなるかな
movabs rax, offset flat hogehoge
gasだとこうなるかな
272デフォルトの名無しさん
2018/09/29(土) 09:36:52.97ID:31v81hqm273デフォルトの名無しさん
2018/09/29(土) 10:00:32.42ID:31v81hqm Linuxでx86_64のgccでコンパイルしたものをとアセンブラのリンクする時に
lea rax, hogehoge
これや
mov rax, hogehoge
これをやるとリンク時にエラーが出るね
lea rax, hogehoge[rip]
mov rax, hogehoge[rip]
こうしないといけないみたい
lea rax, hogehoge
これや
mov rax, hogehoge
これをやるとリンク時にエラーが出るね
lea rax, hogehoge[rip]
mov rax, hogehoge[rip]
こうしないといけないみたい
274デフォルトの名無しさん
2018/09/29(土) 12:31:21.31ID:1LSQxS0k >>273
x64 独特の事情からかんがみて、言いたいことは分かってるつもりだが、
一応、MASM の元々の書き方の仕様では、C言語で言うと、
mov rax, hogehoe[rip] ; rax = *(rip + &hogehoge)
mov rax, hogehoe ; rax = *(&hogehoge)
の「意味」なので、本来は、働きが異なるのでその辺は注意を払う必要がある。
x64 だと、メモリオペランドでは、「絶対アドレス指定」より、
「rip 相対」が短いコードになり、なおかつその場合は、
disp 部分に 64BIT値が入れられないので色々と話が複雑になるけれど。
( gcc(gas)でどう意味に解釈されているかは知らないけど。 )
x64 独特の事情からかんがみて、言いたいことは分かってるつもりだが、
一応、MASM の元々の書き方の仕様では、C言語で言うと、
mov rax, hogehoe[rip] ; rax = *(rip + &hogehoge)
mov rax, hogehoe ; rax = *(&hogehoge)
の「意味」なので、本来は、働きが異なるのでその辺は注意を払う必要がある。
x64 だと、メモリオペランドでは、「絶対アドレス指定」より、
「rip 相対」が短いコードになり、なおかつその場合は、
disp 部分に 64BIT値が入れられないので色々と話が複雑になるけれど。
( gcc(gas)でどう意味に解釈されているかは知らないけど。 )
275デフォルトの名無しさん
2018/09/29(土) 12:34:45.26ID:1LSQxS0k >>274
元々の、masm の syntax 的には、
mov rax,[addr] ;絶対アドレス指定
と、
mov rax,[rip + (addr - offset label1)] ;相対アドレス指定
label1:
が rax に入る値が同じになるハズ。
元々の、masm の syntax 的には、
mov rax,[addr] ;絶対アドレス指定
と、
mov rax,[rip + (addr - offset label1)] ;相対アドレス指定
label1:
が rax に入る値が同じになるハズ。
276デフォルトの名無しさん
2018/09/29(土) 12:40:11.70ID:1LSQxS0k >>274
ちなみに、x86(IA32)モードでは、
[addr]
の ModRM のオペランドのマシン語 encode と全く同じ encode が、
x64(AMD64)では、
[rip + rel32]
になってしまって、しかも後者には、rel32 のための disp32 の4BYTE値が、
ModRM の直後に埋め込まれる仕様になっている。
これは、色々と誤解を招きやすい仕様で、初心者に混乱なく説明するのが難しくなってしまう。
ちなみに、x86(IA32)モードでは、
[addr]
の ModRM のオペランドのマシン語 encode と全く同じ encode が、
x64(AMD64)では、
[rip + rel32]
になってしまって、しかも後者には、rel32 のための disp32 の4BYTE値が、
ModRM の直後に埋め込まれる仕様になっている。
これは、色々と誤解を招きやすい仕様で、初心者に混乱なく説明するのが難しくなってしまう。
277デフォルトの名無しさん
2018/09/29(土) 13:18:43.07ID:31v81hqm >>274
MASMだとx64で
mov rax, hogehoge
こう書くと
mov rax, [hogehoge+rip]
の意味になるよ
マシン語は48 8B 05 xxxxxxxxでRIP相対の32bitDISPの解釈になる
Linuxのgccやgasだと
mov rax, hogehoge
これが32bitの絶対アドレスと解釈される模様
マシン語は48 8b 04 25 xxxxxxxxと
スケールインデックスの基数を持たない32bitDISPになってしまってる
これだとRIP相対にならないのでリンク時にエラーになる
mov rax, hogehoeg[rip]
これだとマシン語は48 8b 05 xxxxxxxxとRIP相対の32bitDISPになる
Linuxのgccやgasで64bit絶対アドレス読み込みや64bit絶対アドレス指定のデータロードは別のニーモニックになる
movabs rax, offset flat: hogehoge
マシン語は48 b8 xxxxxxxxxxxxxxxx
movabs rax, hogehoge
マシン語は48 a1 xxxxxxxxxxxxxxxx
(64bit絶対アドレス指定のデータロードはraxのみ)
MASMだとx64で
mov rax, hogehoge
こう書くと
mov rax, [hogehoge+rip]
の意味になるよ
マシン語は48 8B 05 xxxxxxxxでRIP相対の32bitDISPの解釈になる
Linuxのgccやgasだと
mov rax, hogehoge
これが32bitの絶対アドレスと解釈される模様
マシン語は48 8b 04 25 xxxxxxxxと
スケールインデックスの基数を持たない32bitDISPになってしまってる
これだとRIP相対にならないのでリンク時にエラーになる
mov rax, hogehoeg[rip]
これだとマシン語は48 8b 05 xxxxxxxxとRIP相対の32bitDISPになる
Linuxのgccやgasで64bit絶対アドレス読み込みや64bit絶対アドレス指定のデータロードは別のニーモニックになる
movabs rax, offset flat: hogehoge
マシン語は48 b8 xxxxxxxxxxxxxxxx
movabs rax, hogehoge
マシン語は48 a1 xxxxxxxxxxxxxxxx
(64bit絶対アドレス指定のデータロードはraxのみ)
278デフォルトの名無しさん
2018/09/29(土) 13:25:59.67ID:31v81hqm ちなみにMASMで
mov rax, offset hogehoge
こう書くと
マシン語は48 b8 xxxxxxxxxxxxxxxx
となる
mov rax, offset hogehoge
こう書くと
マシン語は48 b8 xxxxxxxxxxxxxxxx
となる
279デフォルトの名無しさん
2018/09/29(土) 13:37:18.16ID:31v81hqm MASMは実用性を重視した仕様で
gccやgasはより厳密な仕様になってる言えるな
gccやgasはより厳密な仕様になってる言えるな
280デフォルトの名無しさん
2018/09/29(土) 13:55:45.43ID:31v81hqm そもそもMASMのx64版で
mov rax, [hogehoge+rip]
や
mov rax, hogehoge[rip]
こうするとエラーになるよ
mov rax, [hogehoge+rip]
や
mov rax, hogehoge[rip]
こうするとエラーになるよ
281デフォルトの名無しさん
2018/09/29(土) 14:34:50.49ID:1VwJZM7J >>277
>MASMだとx64で
>mov rax, hogehoge
>こう書くと
>mov rax, [hogehoge+rip]
>の意味になるよ
>マシン語は48 8B 05 xxxxxxxxでRIP相対の32bitDISPの解釈になる
言いたいことが間違っているわけではないけど、厳密には、
MASMだとx64で
mov rax, hogehoge
と書くと、
mov rax, [rip + (offset hogehoge - offset label1)]
label1:
の「意味になる」。
>MASMだとx64で
>mov rax, hogehoge
>こう書くと
>mov rax, [hogehoge+rip]
>の意味になるよ
>マシン語は48 8B 05 xxxxxxxxでRIP相対の32bitDISPの解釈になる
言いたいことが間違っているわけではないけど、厳密には、
MASMだとx64で
mov rax, hogehoge
と書くと、
mov rax, [rip + (offset hogehoge - offset label1)]
label1:
の「意味になる」。
282デフォルトの名無しさん
2018/09/29(土) 14:36:51.71ID:1VwJZM7J そもそも、IA32までは、jmp, call 以外ではRIP相対は無かったので、
RIP相対については、masm も gas も、今のところ書式(syntax)的に
無理がある気がする。
RIP相対については、masm も gas も、今のところ書式(syntax)的に
無理がある気がする。
283デフォルトの名無しさん
2018/09/29(土) 14:39:38.93ID:1VwJZM7J つまり、今のところメモリオペランドの syntax に一貫性がなくなってきてしまっていると思う。
284デフォルトの名無しさん
2018/09/29(土) 15:05:27.10ID:31v81hqm285デフォルトの名無しさん
2018/09/29(土) 15:07:28.65ID:1VwJZM7J286デフォルトの名無しさん
2018/09/29(土) 15:08:54.79ID:31v81hqm MASMは実用性を重視して
mov rax, hogehoge
こういう書式
gcc、gasはより厳密に
mov rax, hogehoge[rip]
あくまでそういう決まりごとってこと
書式は違ってくるが
そもそもVisual C++やMASMとgcc、gasでは違うところが多すぎるから問題ない
gccやgasではアセンブラはデフォルトではAT&T記法だしな
mov rax, hogehoge
こういう書式
gcc、gasはより厳密に
mov rax, hogehoge[rip]
あくまでそういう決まりごとってこと
書式は違ってくるが
そもそもVisual C++やMASMとgcc、gasでは違うところが多すぎるから問題ない
gccやgasではアセンブラはデフォルトではAT&T記法だしな
287デフォルトの名無しさん
2018/09/29(土) 15:10:56.60ID:31v81hqm288デフォルトの名無しさん
2018/09/29(土) 15:13:20.76ID:31v81hqm こういう変なのがアスペってやつか
289デフォルトの名無しさん
2018/09/29(土) 15:18:29.23ID:1VwJZM7J >>287
C 言語での、*(&hogehoge) の MASM 版は、意味的には、
[offset hogehoge]
になって、ちょうどそれは、「hogehoge」 の意味に戻るはずなんだけど、
実際に masm でやってみると、変になる。記憶によると、masm では、
[hogehoge]
が hogehoge と書いたのと同じ意味になったはず
(論理的にはそんなはずは無いんだけども)。
C 言語での、*(&hogehoge) の MASM 版は、意味的には、
[offset hogehoge]
になって、ちょうどそれは、「hogehoge」 の意味に戻るはずなんだけど、
実際に masm でやってみると、変になる。記憶によると、masm では、
[hogehoge]
が hogehoge と書いたのと同じ意味になったはず
(論理的にはそんなはずは無いんだけども)。
290デフォルトの名無しさん
2018/09/29(土) 15:19:17.57ID:1VwJZM7J >>288
アスペかも知れんけど、数学は主席みたいな感じだったよ。
アスペかも知れんけど、数学は主席みたいな感じだったよ。
291デフォルトの名無しさん
2018/09/29(土) 15:23:02.46ID:P6L1chXc C言語との対応関係も知らずにアセンブラ語ってたとは驚き
で、また火病って連投してるね
で、また火病って連投してるね
292デフォルトの名無しさん
2018/09/29(土) 15:24:36.40ID:1VwJZM7J こういうのが2ch/5chの問題点なんだよな・・・。
293デフォルトの名無しさん
2018/09/29(土) 15:29:01.40ID:31v81hqm294デフォルトの名無しさん
2018/09/29(土) 15:32:55.38ID:P6L1chXc295デフォルトの名無しさん
2018/09/29(土) 15:37:30.74ID:31v81hqm296デフォルトの名無しさん
2018/09/29(土) 15:38:31.02ID:31v81hqm 実際に試してみればわかることだよ
297デフォルトの名無しさん
2018/09/29(土) 15:41:02.87ID:31v81hqm ID:1VwJZM7Jは論理的にとか書いてるが
実際のアセンブラの仕様を無視して、アセンブラで通らない命令書いてドヤ顔してるやつ
コンピュータなんて論理的におかしい命令とか普通にあるだろ
アスペはそういうのが我慢ならないらしい
実際のアセンブラの仕様を無視して、アセンブラで通らない命令書いてドヤ顔してるやつ
コンピュータなんて論理的におかしい命令とか普通にあるだろ
アスペはそういうのが我慢ならないらしい
298デフォルトの名無しさん
2018/09/29(土) 15:43:55.02ID:P6L1chXc299デフォルトの名無しさん
2018/09/29(土) 15:46:13.22ID:31v81hqm >>298
あなたもx86_64のアセンブラの仕様関して全く理解してないのはわかった
あなたもしたり顔で語るなよ
ここに書かれてる命令を実際にアセンブルしてその結果を見れば誰が正しいことを言ってるかわかるはず
あなたもx86_64のアセンブラの仕様関して全く理解してないのはわかった
あなたもしたり顔で語るなよ
ここに書かれてる命令を実際にアセンブルしてその結果を見れば誰が正しいことを言ってるかわかるはず
300デフォルトの名無しさん
2018/09/29(土) 15:50:43.93ID:31v81hqm301デフォルトの名無しさん
2018/09/29(土) 15:50:52.23ID:P6L1chXc302デフォルトの名無しさん
2018/09/29(土) 15:52:36.05ID:IuTgmxg/ 論理的におかしい命令なんかない
処理されるまでの過程は別にして計算機は命令されたとおりに動く
処理結果がおかしいのはキミラのオツムの問題
そもそもアセンブラなんか
キャッシュミスをできるだけむりやり回避するためにインラインアセンブラ書くとか
非常に明確な理由がないかぎりまず使われることなんかまずない
つまりココではアホ同士がアホなことでもめてる
処理されるまでの過程は別にして計算機は命令されたとおりに動く
処理結果がおかしいのはキミラのオツムの問題
そもそもアセンブラなんか
キャッシュミスをできるだけむりやり回避するためにインラインアセンブラ書くとか
非常に明確な理由がないかぎりまず使われることなんかまずない
つまりココではアホ同士がアホなことでもめてる
303デフォルトの名無しさん
2018/09/29(土) 15:54:58.28ID:31v81hqm >>301
> x64 独特の事情からかんがみて、言いたいことは分かってるつもりだが、
> 一応、MASM の元々の書き方の仕様では、C言語で言うと、
>
> mov rax, hogehoe[rip] ; rax = *(rip + &hogehoge)
> mov rax, hogehoe ; rax = *(&hogehoge)
>
> の「意味」なので、本来は、働きが異なるのでその辺は注意を払う必要がある。
そもそもMASMでは
mov rax, hogehoe[rip]
こんな記述は未サポート
mov rax, hogehoe
これが*(rip + hogehoge)の意味
> x64 独特の事情からかんがみて、言いたいことは分かってるつもりだが、
> 一応、MASM の元々の書き方の仕様では、C言語で言うと、
>
> mov rax, hogehoe[rip] ; rax = *(rip + &hogehoge)
> mov rax, hogehoe ; rax = *(&hogehoge)
>
> の「意味」なので、本来は、働きが異なるのでその辺は注意を払う必要がある。
そもそもMASMでは
mov rax, hogehoe[rip]
こんな記述は未サポート
mov rax, hogehoe
これが*(rip + hogehoge)の意味
304デフォルトの名無しさん
2018/09/29(土) 15:57:13.97ID:31v81hqm >>302
アスペ君は
mov rax, hogehoge
これが*(hogehoge + rip)の意味になるところが気に入らなくて突っ込みいれてるだけ
でも、実際に仕様なのだからしょうがないってこと
アスペ君は
mov rax, hogehoge
これが*(hogehoge + rip)の意味になるところが気に入らなくて突っ込みいれてるだけ
でも、実際に仕様なのだからしょうがないってこと
305デフォルトの名無しさん
2018/09/29(土) 16:01:34.18ID:P6L1chXc >>273みたいなこと書く奴が「理解できてる」はずないだろw
今回も「リンク時にエラーが出る」とか言ってさ
今回も「リンク時にエラーが出る」とか言ってさ
306デフォルトの名無しさん
2018/09/29(土) 16:06:06.66ID:31v81hqm307デフォルトの名無しさん
2018/09/29(土) 16:18:56.60ID:P6L1chXc 32bitではきちんと理解してなくてもなんとかなったってだけなの
x64知らないなら出てこなきゃいいのに
x64知らないなら出てこなきゃいいのに
308デフォルトの名無しさん
2018/09/29(土) 16:24:58.15ID:31v81hqm >>307
x86_64をわかってないのはあなただろ
MASMでは
mov rax, hogehoge
こう書く仕様だっての
gcc、gasでは
mov rax, hogehoge[rip]
こう書くのが仕様
ただそれだけ
マシン語ではどちらも48 8b 05 xxxxxxxxとRIP相対の32bitDISPになる
x86_64をわかってないのはあなただろ
MASMでは
mov rax, hogehoge
こう書く仕様だっての
gcc、gasでは
mov rax, hogehoge[rip]
こう書くのが仕様
ただそれだけ
マシン語ではどちらも48 8b 05 xxxxxxxxとRIP相対の32bitDISPになる
309デフォルトの名無しさん
2018/09/29(土) 16:32:57.40ID:31v81hqm offsetを使ったものも
MASMでは
mov rax, offset hogehoge
これでマシン語は48 b8 xxxxxxxxxxxxxxxxと64bit絶対アドレスになる
gcc、gasでは
movabs rax, offset flat: hogehoge
これでマシン語は48 b8 xxxxxxxxxxxxxxxxと64bit絶対アドレスになる
leaを使うと
MASMでは
lea rax, hogehoge
これでマシン語は48 8d 05 xxxxxxxxとRIP相対32bitDISPになる
gcc、gasだと
lea rax, hogehoge[rip]
これでマシン語は48 8d 05 xxxxxxxxとRIP相対32bitDISPになる
MASMでは
mov rax, offset hogehoge
これでマシン語は48 b8 xxxxxxxxxxxxxxxxと64bit絶対アドレスになる
gcc、gasでは
movabs rax, offset flat: hogehoge
これでマシン語は48 b8 xxxxxxxxxxxxxxxxと64bit絶対アドレスになる
leaを使うと
MASMでは
lea rax, hogehoge
これでマシン語は48 8d 05 xxxxxxxxとRIP相対32bitDISPになる
gcc、gasだと
lea rax, hogehoge[rip]
これでマシン語は48 8d 05 xxxxxxxxとRIP相対32bitDISPになる
310デフォルトの名無しさん
2018/09/29(土) 16:43:03.59ID:31v81hqm x86_64のRIP相対アドレッシングは歴史的には
32bitの時の32bit絶対アドレッシングの仕様を変更してRIP相対をねじ込んだ形だからね
アセンブラの記述的に、論理的におかしくてもしょうがないんだよ
論理的なものよりも実用性を重視したのがMASM
より論理的に厳密にしたのがgasということだろうな
32bitの時の32bit絶対アドレッシングの仕様を変更してRIP相対をねじ込んだ形だからね
アセンブラの記述的に、論理的におかしくてもしょうがないんだよ
論理的なものよりも実用性を重視したのがMASM
より論理的に厳密にしたのがgasということだろうな
311デフォルトの名無しさん
2018/09/29(土) 17:11:34.41ID:kF9GSkBg ちょっと質問なんだけど
dataセクションは32bitアドレス内にないとアクセスできないってこと?
extern int aaa[10];
int bbb (int i) {return aaa[i];}
このコードがこんな感じになってたんだけど
00000000004011a0 <bbb>:
4011a0: 48 63 ff movslq %edi,%rdi
4011a3: 8b 04 bd 40 40 40 00 mov 0x404040(,%rdi,4),%eax
4011aa: c3 retq
aaaがdataセクションの0x404040にあったからこうやってアクセスできたけど
32bit超えてたらこの命令は翻訳できない?
dataセクションは32bitアドレス内にないとアクセスできないってこと?
extern int aaa[10];
int bbb (int i) {return aaa[i];}
このコードがこんな感じになってたんだけど
00000000004011a0 <bbb>:
4011a0: 48 63 ff movslq %edi,%rdi
4011a3: 8b 04 bd 40 40 40 00 mov 0x404040(,%rdi,4),%eax
4011aa: c3 retq
aaaがdataセクションの0x404040にあったからこうやってアクセスできたけど
32bit超えてたらこの命令は翻訳できない?
312デフォルトの名無しさん
2018/09/29(土) 17:23:41.07ID:31v81hqm >>311
アセンブラのみではそういうことはないけど、C言語とリンクする場合はそうなるね
64bitでも通常はグローバル変数などのシンボルやジャンプ先のラベルは32bitを前提としてコンパイルされている
x86_64だとRIP相対の32bitDISPで届かないところにはアクセスできない
他のCPUでも似たようなもの
Windowsだと回避方法はない
LinuxだとHPCなどで-mcmodel=mediumを指定することで回避できる方法はあるけどね
アセンブラのみではそういうことはないけど、C言語とリンクする場合はそうなるね
64bitでも通常はグローバル変数などのシンボルやジャンプ先のラベルは32bitを前提としてコンパイルされている
x86_64だとRIP相対の32bitDISPで届かないところにはアクセスできない
他のCPUでも似たようなもの
Windowsだと回避方法はない
LinuxだとHPCなどで-mcmodel=mediumを指定することで回避できる方法はあるけどね
313デフォルトの名無しさん
2018/09/29(土) 17:34:12.56ID:mdNhb+fJ >>290
首席のことか
首席のことか
314デフォルトの名無しさん
2018/09/29(土) 17:35:24.77ID:31v81hqm >>311を俺の環境でgccでコンパイルしてみたらこうなった
オブジェクトファイルなのでアドレスは00 00 00 00のまま
gccのバージョンは7.3.0
0000000000000000 <bbb>:
0: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax # 7 <bbb+0x7>
7: 48 63 ff movslq %edi,%rdi
a: 8b 04 b8 mov (%rax,%rdi,4),%eax
d: c3 retq
オブジェクトファイルなのでアドレスは00 00 00 00のまま
gccのバージョンは7.3.0
0000000000000000 <bbb>:
0: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax # 7 <bbb+0x7>
7: 48 63 ff movslq %edi,%rdi
a: 8b 04 b8 mov (%rax,%rdi,4),%eax
d: c3 retq
315デフォルトの名無しさん
2018/09/29(土) 17:36:30.80ID:kF9GSkBg ありがとう
>>311のはa.outにしてアドレスが分かるようにした後だったから
>>311のはa.outにしてアドレスが分かるようにした後だったから
316デフォルトの名無しさん
2018/09/29(土) 17:37:16.65ID:31v81hqm AT&Tニーモニックの貼ってしまった
Intelニーモニックはこっち
0000000000000000 <bbb>:
0: 48 8d 05 00 00 00 00 lea rax,[rip+0x0] # 7 <bbb+0x7>
7: 48 63 ff movsxd rdi,edi
a: 8b 04 b8 mov eax,DWORD PTR [rax+rdi*4]
d: c3 ret
Intelニーモニックはこっち
0000000000000000 <bbb>:
0: 48 8d 05 00 00 00 00 lea rax,[rip+0x0] # 7 <bbb+0x7>
7: 48 63 ff movsxd rdi,edi
a: 8b 04 b8 mov eax,DWORD PTR [rax+rdi*4]
d: c3 ret
317デフォルトの名無しさん
2018/09/29(土) 17:42:37.03ID:kF9GSkBg318デフォルトの名無しさん
2018/09/29(土) 18:11:22.67ID:31v81hqm 俺のもLinuxだよ
319デフォルトの名無しさん
2018/09/29(土) 18:29:50.29ID:kF9GSkBg 7.3でも5.3でも>>311のになった
configure 設定: ../gcc-7.3.0/configure --prefix=/usr --libdir=/usr/lib64 --mandir=/usr/man --infodir=/usr/info --enable-shared
--enable-bootstrap --enable-languages=ada,brig,c,c++,fortran,go,lto,objc --enable-threads=posix --enable-checking=release
--enable-objc-gc --with-system-zlib --enable-libstdcxx-dual-abi --with-default-libstdcxx-abi=new --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --enable-lto --disable-install-libiberty --with-gnu-ld --verbose --with-arch-directory=amd64
--disable-gtktest --disable-multilib --target=x86_64-slackware-linux --build=x86_64-slackware-linux --host=x86_64-slackware-linux
スレッドモデル: posix
gcc バージョン 7.3.0 (GCC)
configure 設定が違うのかな
configure 設定: ../gcc-7.3.0/configure --prefix=/usr --libdir=/usr/lib64 --mandir=/usr/man --infodir=/usr/info --enable-shared
--enable-bootstrap --enable-languages=ada,brig,c,c++,fortran,go,lto,objc --enable-threads=posix --enable-checking=release
--enable-objc-gc --with-system-zlib --enable-libstdcxx-dual-abi --with-default-libstdcxx-abi=new --disable-libunwind-exceptions
--enable-__cxa_atexit --enable-libssp --enable-lto --disable-install-libiberty --with-gnu-ld --verbose --with-arch-directory=amd64
--disable-gtktest --disable-multilib --target=x86_64-slackware-linux --build=x86_64-slackware-linux --host=x86_64-slackware-linux
スレッドモデル: posix
gcc バージョン 7.3.0 (GCC)
configure 設定が違うのかな
320デフォルトの名無しさん
2018/09/29(土) 18:31:39.06ID:1VwJZM7J321デフォルトの名無しさん
2018/09/29(土) 18:37:57.88ID:1VwJZM7J >>320
理解のポイントは、(64BIT)命令ポインタ rip は、CPUが、ModRM
の間接(メモリ)オペランドを解釈する時には、命令の直後の
アドレスを指しているかのようにみなされて、丁度、
rip = offset label1
または、
rip = &label1
であるかのように解釈されるということ。
理解のポイントは、(64BIT)命令ポインタ rip は、CPUが、ModRM
の間接(メモリ)オペランドを解釈する時には、命令の直後の
アドレスを指しているかのようにみなされて、丁度、
rip = offset label1
または、
rip = &label1
であるかのように解釈されるということ。
322デフォルトの名無しさん
2018/09/29(土) 18:52:23.15ID:31v81hqm323デフォルトの名無しさん
2018/09/29(土) 19:02:53.64ID:31v81hqm >>319
自分でビルドしたやつじゃないけど
gcc -vをやると
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.3.0-27ubuntu1~18.04'
--with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++
--prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie
--with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror
--with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
自分でビルドしたやつじゃないけど
gcc -vをやると
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.3.0-27ubuntu1~18.04'
--with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++
--prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie
--with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror
--with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
324デフォルトの名無しさん
2018/09/29(土) 19:23:24.57ID:kF9GSkBg 分かった-fPICつけると>>314と同じになった
325デフォルトの名無しさん
2018/09/29(土) 19:30:06.39ID:P6L1chXc MASMはデフォルトがrip相対だからな
offset演算子使った段階でアドレスではなくただの数値になってるのが理解できんのか
だから絶対アドレスになんだよ
offset演算子使った段階でアドレスではなくただの数値になってるのが理解できんのか
だから絶対アドレスになんだよ
326デフォルトの名無しさん
2018/09/29(土) 19:42:48.86ID:31v81hqm327デフォルトの名無しさん
2018/09/29(土) 19:54:13.97ID:31v81hqm 変な突っ込みする人がいるから書くが
CPUの命令的にはx86_64で
mov rax, offset hogehoge
これは64bitのimmを読み込むマシン語に変換される
要するにただの64bitの数値を読み込む命令
マシン語は48 b8 xxxxxxxxxxxxxxxx
ただ、アセンブラはちゃんと64bit immの部分が64bitの絶対アドレスということを認識してる
だから再配置された時に64bit絶対アドレスが再配置後のhogehogeのアドレスに置き換わる
CPUの命令的にはx86_64で
mov rax, offset hogehoge
これは64bitのimmを読み込むマシン語に変換される
要するにただの64bitの数値を読み込む命令
マシン語は48 b8 xxxxxxxxxxxxxxxx
ただ、アセンブラはちゃんと64bit immの部分が64bitの絶対アドレスということを認識してる
だから再配置された時に64bit絶対アドレスが再配置後のhogehogeのアドレスに置き換わる
328デフォルトの名無しさん
2018/09/29(土) 20:19:25.44ID:31v81hqm こんなことみんな知ってるとは思うが
実際に64bit絶対アドレスが確定するのはプログラムがメモリ上にロードされる時
このときに、絶対アドレスなどの情報が配置されるアドレスによって正しい値に書き換えられる
実際に64bit絶対アドレスが確定するのはプログラムがメモリ上にロードされる時
このときに、絶対アドレスなどの情報が配置されるアドレスによって正しい値に書き換えられる
329デフォルトの名無しさん
2018/09/29(土) 21:07:16.90ID:P6L1chXc そもそも
lea rax, [hogehoge]
って書いときゃNASMでも通るのに
>data01のアドレスを読み込みたかったら
>mov eax, offset data01
>こうすること
なんて教えようとするのかね?
lea rax, [hogehoge]
って書いときゃNASMでも通るのに
>data01のアドレスを読み込みたかったら
>mov eax, offset data01
>こうすること
なんて教えようとするのかね?
330デフォルトの名無しさん
2018/09/29(土) 21:11:28.97ID:P6L1chXc MASMって
mov eax, [rsp][16]
mov eax, [rsi][rcx]
みたいな変態な表現も通るんだよな
mov eax, [rsp][16]
mov eax, [rsi][rcx]
みたいな変態な表現も通るんだよな
331デフォルトの名無しさん
2018/09/30(日) 00:47:29.69ID:KtGjBt6/ Microsoft (R) Macro Assembler (x64) Version 12.00.40629.0
mov al, hogehoge
mov al, [hogehoge]
mov rax, offset flat:hogehoge ; error A2006:undefined symbol : flat
lea rax, [hogehoge]
lea rax, offset flat:hogehoge ; error A2006:undefined symbol : flat
lea rax, hogehoge
14.00.24210.0でも同じだな
mov al, hogehoge
mov al, [hogehoge]
mov rax, offset flat:hogehoge ; error A2006:undefined symbol : flat
lea rax, [hogehoge]
lea rax, offset flat:hogehoge ; error A2006:undefined symbol : flat
lea rax, hogehoge
14.00.24210.0でも同じだな
332デフォルトの名無しさん
2018/09/30(日) 00:54:08.42ID:KtGjBt6/ clが吐いた.codでは
lea rax, offset flat:hogehoge
みたいな表記になってるけど、ml64は受け付けない
lea rax, offset flat:hogehoge
みたいな表記になってるけど、ml64は受け付けない
333デフォルトの名無しさん
2018/09/30(日) 01:03:38.57ID:KtGjBt6/ mov eax, offset hogehoge
とやってもエラーも出ないんだよね 当然だけど
0000001A 48/ B8 0000000000000000 E mov rax, offset hogehoge
00000024 B8 00000000 E mov eax, offset hogehoge
とやってもエラーも出ないんだよね 当然だけど
0000001A 48/ B8 0000000000000000 E mov rax, offset hogehoge
00000024 B8 00000000 E mov eax, offset hogehoge
334236
2018/09/30(日) 01:18:13.92ID:PppEulsk なんか説明が不適切だったせいで偉いことになってしまった・・・すまん
とりあえずAMD64のプログラミングマニュアルとIA32/EM64Tの日本語プログラミングマニュアルはダウンロードしてあります
やりたいことは演算ではなくて特殊?な例外処理です。C風に書くと
unsigned int *a;
unsigned int b;
&a = 0x00001000; // アドレスをセット
*a = 0x00888888; // 0x00001000へ値を書き込み
b = *(&a + 1); // 0x00001004の値を読み出し。読み出される値は0x00001000の値に0x0100を加算した物
// bの中身は0x00888988
みたいな感じかな。メモリの読み書き動作に任意の処理を挟みたいです。自分なりにこのような動作をさせる方法を考えた結果
・該当する仮想アドレスにメモリを割り当てない
・アクセスすると発生するページフォールトをハンドリングする
・ハンドラ中で値の処理とアクセス元のコードが行うつもりだった読み書き動作もする
・ページフォールトを発生させた次の命令から実行を再開する
となったのですがこれらを高級言語のみで実装するのは無理そうな気がするのでアセンブラを読み書きできる必要があるかなと・・・
各OSごとの例外処理がらみの情報も必要ですがこの辺もなかなか見つけられないです
とりあえずAMD64のプログラミングマニュアルとIA32/EM64Tの日本語プログラミングマニュアルはダウンロードしてあります
やりたいことは演算ではなくて特殊?な例外処理です。C風に書くと
unsigned int *a;
unsigned int b;
&a = 0x00001000; // アドレスをセット
*a = 0x00888888; // 0x00001000へ値を書き込み
b = *(&a + 1); // 0x00001004の値を読み出し。読み出される値は0x00001000の値に0x0100を加算した物
// bの中身は0x00888988
みたいな感じかな。メモリの読み書き動作に任意の処理を挟みたいです。自分なりにこのような動作をさせる方法を考えた結果
・該当する仮想アドレスにメモリを割り当てない
・アクセスすると発生するページフォールトをハンドリングする
・ハンドラ中で値の処理とアクセス元のコードが行うつもりだった読み書き動作もする
・ページフォールトを発生させた次の命令から実行を再開する
となったのですがこれらを高級言語のみで実装するのは無理そうな気がするのでアセンブラを読み書きできる必要があるかなと・・・
各OSごとの例外処理がらみの情報も必要ですがこの辺もなかなか見つけられないです
335デフォルトの名無しさん
2018/09/30(日) 04:51:47.08ID:fqhkGGw5 >>322
64bitのcl.exeが吐き出すアセンブラ出力はml64.exeでそのままではアセンブル通らないよ
何箇所か、修正が必要になる
ちなみに32bitのcl.exeが吐き出すアセンブラ出力はそのまま32bitのml.exeでアセンブルできる
>>333
mov eax, offset hogehoge
これをx64用のml64.exeでアセンブルしてもエラーは起きないが
リンク時にこのエラーが出るよ
error LNK2017: 'ADDR32' relocation to
'hogehoge' invalid without /LARGEADDRESSAWARE:NO
LINK : fatal error LNK1165: link failed because of fixup errors
64bitのアドレスを32bit絶対アドレスに切り詰めてるのだから当たり前だけど
mov rax, offset hogehoge
これは全く問題ない
アセンブルもリンクも正常に行われるし、正常にプログラムを実行できる
64bitのcl.exeが吐き出すアセンブラ出力はml64.exeでそのままではアセンブル通らないよ
何箇所か、修正が必要になる
ちなみに32bitのcl.exeが吐き出すアセンブラ出力はそのまま32bitのml.exeでアセンブルできる
>>333
mov eax, offset hogehoge
これをx64用のml64.exeでアセンブルしてもエラーは起きないが
リンク時にこのエラーが出るよ
error LNK2017: 'ADDR32' relocation to
'hogehoge' invalid without /LARGEADDRESSAWARE:NO
LINK : fatal error LNK1165: link failed because of fixup errors
64bitのアドレスを32bit絶対アドレスに切り詰めてるのだから当たり前だけど
mov rax, offset hogehoge
これは全く問題ない
アセンブルもリンクも正常に行われるし、正常にプログラムを実行できる
336デフォルトの名無しさん
2018/09/30(日) 17:26:28.46ID:KtGjBt6/ >>335
NASM(bits64, default rel)だとエラーになるよ
mov rax, offset hogehoge ; error: comma, colon, decorator or end of line expected after operand
lea rax, hogehoge ; error: invalid combination of opcode and operands
lea rax, [hogehoge] ⇒ 488D05
mov al, hogehoge ⇒ B0
にアセンブルされたりもするけど
MASMでもlea rax, [hogehoge]やmov al, [hogehoge]はNASMと同じマシン語になるはず
Windows 64bitはrip相対使ってるのに、MASMで簡単に絶対アドレスが登場するのがおかしいと思わないのかね
NASM(bits64, default rel)だとエラーになるよ
mov rax, offset hogehoge ; error: comma, colon, decorator or end of line expected after operand
lea rax, hogehoge ; error: invalid combination of opcode and operands
lea rax, [hogehoge] ⇒ 488D05
mov al, hogehoge ⇒ B0
にアセンブルされたりもするけど
MASMでもlea rax, [hogehoge]やmov al, [hogehoge]はNASMと同じマシン語になるはず
Windows 64bitはrip相対使ってるのに、MASMで簡単に絶対アドレスが登場するのがおかしいと思わないのかね
337デフォルトの名無しさん
2018/09/30(日) 21:29:51.77ID:KtGjBt6/ >>334
いまいちやりたいことが分からないんだけど、Windowsでアクセス違反をハンドリングするのは
https://docs.microsoft.com/ja-jp/windows/desktop/Memory/reserving-and-committing-memory
が参考になるんじゃないかな
__except()のフィルタ関数でアクセス違反をチェックして、対象範囲のアドレスだったらVirtualAllocで
コミットして__except()にEXCEPTION_CONTINUE_EXECUTION返せば再実行される
対象範囲外のアドレスはEXCEPTION_CONTINUE_SEARCHを返す必要がある
メモリは事前に予約してないと例外から回復できないみたい
構造化例外処理は
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/seh.html
https://msdn.microsoft.com/ja-jp/library/swezty51.aspx
を読んでみて
いまいちやりたいことが分からないんだけど、Windowsでアクセス違反をハンドリングするのは
https://docs.microsoft.com/ja-jp/windows/desktop/Memory/reserving-and-committing-memory
が参考になるんじゃないかな
__except()のフィルタ関数でアクセス違反をチェックして、対象範囲のアドレスだったらVirtualAllocで
コミットして__except()にEXCEPTION_CONTINUE_EXECUTION返せば再実行される
対象範囲外のアドレスはEXCEPTION_CONTINUE_SEARCHを返す必要がある
メモリは事前に予約してないと例外から回復できないみたい
構造化例外処理は
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/seh.html
https://msdn.microsoft.com/ja-jp/library/swezty51.aspx
を読んでみて
338デフォルトの名無しさん
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と同じマシン語にならない
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と同じマシン語にならない
339デフォルトの名無しさん
2018/10/01(月) 05:43:56.26ID:gNvpqBnl みんなはじめて読むMASMからやり直しだなw
340デフォルトの名無しさん
2018/10/01(月) 05:51:48.63ID:gNvpqBnl >>336
RIP相対32bitdispだとアクセスできない場合が出てくる
シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であって
アセンブラはその制限を受けない
実際にWindowsのEXEファイルは64bit絶対アドレスに対応してて
きちんと再配置してくれるわけだし
RIP相対32bitdispだとアクセスできない場合が出てくる
シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であって
アセンブラはその制限を受けない
実際にWindowsのEXEファイルは64bit絶対アドレスに対応してて
きちんと再配置してくれるわけだし
341デフォルトの名無しさん
2018/10/01(月) 06:38:07.64ID:Z1gvrlLR これこそアスペって奴だよな
質問とは関係ないCPU持ち出して勝手に「語り」をはじめたり、32bitでは1バイト短くなるだの
実用的には0.001%程度しか影響なさそうな絶対アドレスの方が速いだの、C/C++とリンクして使うのが
普通なのに「シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であってアセンブラはその制限を受けない」とか
初心者そっちのけで有害としか思えないような方法垂れ流したりと、他人の迷惑とか全く考えられないんだから
初心者にはMASMとNASMで同じように使えればそれで十分
完全に同じマシン語になるかどうかなんて知るか
特に絶対アドレスなんてWin64には不要と考えるべき
初期化領域以外の動的確保されたメモリはポインタ経由のアクセスが基本なんだから
質問とは関係ないCPU持ち出して勝手に「語り」をはじめたり、32bitでは1バイト短くなるだの
実用的には0.001%程度しか影響なさそうな絶対アドレスの方が速いだの、C/C++とリンクして使うのが
普通なのに「シンボルがRIP相対2GBに制限されるなどはあくまでCコンパイラの制限であってアセンブラはその制限を受けない」とか
初心者そっちのけで有害としか思えないような方法垂れ流したりと、他人の迷惑とか全く考えられないんだから
初心者にはMASMとNASMで同じように使えればそれで十分
完全に同じマシン語になるかどうかなんて知るか
特に絶対アドレスなんてWin64には不要と考えるべき
初期化領域以外の動的確保されたメモリはポインタ経由のアクセスが基本なんだから
342デフォルトの名無しさん
2018/10/01(月) 06:45:27.19ID:Z1gvrlLR >>334
こういう状態なんで、334は全く悪くないから気にしなくていいよ
アクセス違反を検出して対応するのは、使ってみたいところがあったのでちょうどいい機会だった
一応自分の書いたテストプログラムを上げとくね
https://pastebin.com/b5gZXxCF
こういう状態なんで、334は全く悪くないから気にしなくていいよ
アクセス違反を検出して対応するのは、使ってみたいところがあったのでちょうどいい機会だった
一応自分の書いたテストプログラムを上げとくね
https://pastebin.com/b5gZXxCF
343デフォルトの名無しさん
2018/10/01(月) 06:51:19.23ID:gNvpqBnl344デフォルトの名無しさん
2018/10/01(月) 07:02:13.01ID:gNvpqBnl はじめて読むMASM
79ページ目
データラベルは、マシンご命令のニーモニックのなかで、データを格納す
るメモリを参照するために使用することができます。次の図3−10をみてく
ださい。この図では、違いを対比させるために次節で解説するOFFSET擬似
命令の役割を併せて図解してあります。
この場合、MESSAGEというデータラベルは01C3Hというアドレスに対応
しています。コードラベルの場合は、ラベル名がアドレスそのものと対応し
ていましたが、データラベルの場合にはちょっと違います。このことは重要
ですからよく覚えておいて下さい。
たとえば、SYMDEBのようにアドレスを直接数値で指定する場合、そのア
ドレスのメモリの内容を参照するには、
MOV DX, [01C3H]
のようにアドレスを[]で囲みます。これに対し、アセンブラのソースプロ
グラムでは、
MOV
79ページ目
データラベルは、マシンご命令のニーモニックのなかで、データを格納す
るメモリを参照するために使用することができます。次の図3−10をみてく
ださい。この図では、違いを対比させるために次節で解説するOFFSET擬似
命令の役割を併せて図解してあります。
この場合、MESSAGEというデータラベルは01C3Hというアドレスに対応
しています。コードラベルの場合は、ラベル名がアドレスそのものと対応し
ていましたが、データラベルの場合にはちょっと違います。このことは重要
ですからよく覚えておいて下さい。
たとえば、SYMDEBのようにアドレスを直接数値で指定する場合、そのア
ドレスのメモリの内容を参照するには、
MOV DX, [01C3H]
のようにアドレスを[]で囲みます。これに対し、アセンブラのソースプロ
グラムでは、
MOV
345デフォルトの名無しさん
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を見てじっくり確認してください。
こう書かれてる
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からやりなおしだな
3.6
OFFSET演算子とPTR演算子
OFFSET演算子
[書式] OFFSET ラベル名
データラベルをニーモニック中で使用すると、データ部分のアドレスでは
なく、データを格納したメモリの内容を表しますが、そのメモリのアドレス
はどうやって表すのでしょうか。図3−10で図解してあるので解説するまでも
ありませんが、データラベルに対応するアドレスは、次のように表します
OFFSET データラベル
OFFSET演算子は、ラベルに対して使用する演算子です。ラベルの前にこ
の演算子を付けると、ラベルに対応するアドレスを表す値となります。
例題のプログラムでは図3−11の部分で使われています。これは画面に出
力するメッセージが格納されているアドレス値を、データとして定義してい
る例です。
MASMの文法は16bitの頃から一貫してる
みんなはじめて読むMASMからやりなおしだな
347デフォルトの名無しさん
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で異なる動作にならない方が無難
こっちが言いたいのは、初心者に有用なことが書けないなら「出てくんな」ってことだけ
MASMでもmov al,[hogehoge]やlea rax,[hogehoge]が使えて、NASMと「同じ動作」が期待できて、
「根本的に」書き換えなくても疑似命令やマクロとかを書き換えれば移植できるってのがポイントで
NASMはLinux他とWindowsみたいなマルチプラットフォームのプロジェクトでよく使われてるから
あんたみたいなmov al,hogehogeやり方でNASMに移行すると変なバグに悩まされる可能性があんだよ
特にmov al,hogehogeがイミディエイトでアドレスの一部がコードされるのが酷い
SYMDEBで括弧で括るってのはイミディエイトと区別付かないからそうなってるんだろ
これはNASMで括弧で括るのと同じこと
時代遅れになった本の内容なんてどうでもいい
括弧で括らない表記は、8080時代を踏襲してるのか、インラインアセンブラでのCの変数参照と統一感があるってところだろう
これならNASMで異なる動作にならない方が無難
こっちが言いたいのは、初心者に有用なことが書けないなら「出てくんな」ってことだけ
348デフォルトの名無しさん
2018/10/01(月) 07:55:48.93ID:gNvpqBnl349デフォルトの名無しさん
2018/10/01(月) 07:57:49.96ID:gNvpqBnl それにNASMで慣れるとgccでインラインアセンブラを使うときに困る
gccはx86_64でもインラインアセンブラを扱えるのに
NASMの文法はgccのインラインアセンブラでは通用しないぞ
gccはx86_64でもインラインアセンブラを扱えるのに
NASMの文法はgccのインラインアセンブラでは通用しないぞ
350デフォルトの名無しさん
2018/10/01(月) 08:10:48.59ID:gNvpqBnl 多くの人がOFFSET演算子に対する理解がないようだから書いただけなのに
猛烈に反発してくる変な人がいるだけ
gccでは-mcmodel=largeのオプションを付けてコンパイルすると
movabs rax, offset flat: hogehoge
のような表現がよく出てくる
64bit絶対アドレスを扱うには必ず必要になってくる
猛烈に反発してくる変な人がいるだけ
gccでは-mcmodel=largeのオプションを付けてコンパイルすると
movabs rax, offset flat: hogehoge
のような表現がよく出てくる
64bit絶対アドレスを扱うには必ず必要になってくる
351デフォルトの名無しさん
2018/10/01(月) 09:35:33.25ID:Yquio+NL >>341
アセンブラは、かなり細かいことを理解して無いと使いこなせないかもしれないよ。
それが C/C++ などとは違う点。
ちゃんと、リストファイルを見て、Intel の Instruction 表と照らし合わせて
どの命令が出力されているかを確認し、さらに、OBJやEXEファイルを逆アセンブル
してみて、さらにさらに、ローダーが実際にどのようにロードしたかをデバッガ
で確認する、などをちゃんとしないと、うまくいかないかもしれない。
実際、純正の Visual Studio が出したアセンブリソースが、masm で通らない
などという現象が確認されている事からしても、色々と確認作業が必要だと
思う。
自分はアセンブリ経験が豊富だが、上記のような確認作業をかなり積んだから
こそ使えていたと思う。
アセンブラの出力は、バージョンによっても違っていることがあるかも
知れないし、64BITモードでは、同じニモニックでも異なるマシン語を
出力することもありえる。
さらに言うと、アセンブラ自体が非常に困った仕様になってしまっていることもあり得る。
もともと、アセンブリ言語は、初心者が混乱無く使えるようにはなってないという側面もある。
失礼かもしれないけど、他の言語で豊富な経験を積んで、なおかつ、地頭のいい人限定だよね、もともと。
アセンブラは、かなり細かいことを理解して無いと使いこなせないかもしれないよ。
それが C/C++ などとは違う点。
ちゃんと、リストファイルを見て、Intel の Instruction 表と照らし合わせて
どの命令が出力されているかを確認し、さらに、OBJやEXEファイルを逆アセンブル
してみて、さらにさらに、ローダーが実際にどのようにロードしたかをデバッガ
で確認する、などをちゃんとしないと、うまくいかないかもしれない。
実際、純正の Visual Studio が出したアセンブリソースが、masm で通らない
などという現象が確認されている事からしても、色々と確認作業が必要だと
思う。
自分はアセンブリ経験が豊富だが、上記のような確認作業をかなり積んだから
こそ使えていたと思う。
アセンブラの出力は、バージョンによっても違っていることがあるかも
知れないし、64BITモードでは、同じニモニックでも異なるマシン語を
出力することもありえる。
さらに言うと、アセンブラ自体が非常に困った仕様になってしまっていることもあり得る。
もともと、アセンブリ言語は、初心者が混乱無く使えるようにはなってないという側面もある。
失礼かもしれないけど、他の言語で豊富な経験を積んで、なおかつ、地頭のいい人限定だよね、もともと。
352デフォルトの名無しさん
2018/10/01(月) 09:38:14.45ID:Yquio+NL あと、一度実験した内容を正確に覚える記憶力も必要。
本で書かれていることと実際が違っていることは良くある。
本で書かれていることと実際が違っていることは良くある。
353デフォルトの名無しさん
2018/10/01(月) 10:13:48.86ID:Yquio+NL >>334
例外処理については、詳細な文献と実験調査を行ったことがある。
文献だけでは不十分で、コードをフックするような仕組みによって実験しないと分からない。
教えることは出来るが、ここでは馬鹿にされるだけなのですまんが答えられない。
例外処理については、詳細な文献と実験調査を行ったことがある。
文献だけでは不十分で、コードをフックするような仕組みによって実験しないと分からない。
教えることは出来るが、ここでは馬鹿にされるだけなのですまんが答えられない。
354デフォルトの名無しさん
2018/10/01(月) 10:26:50.53ID:8+wJeq75 IDを換えながらレスをつけてるのか
355デフォルトの名無しさん
2018/10/01(月) 23:50:29.17ID:Z1gvrlLR356デフォルトの名無しさん
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
Windowsならちょっとググッただけでいろいろ出てくるぞ
このあたり見てやればできるのでは?
アセンブラは全く関係ないね
構造化例外処理
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/seh.html
GetExceptionCode
https://msdn.microsoft.com/ja-jp/library/cc428942.aspx
357デフォルトの名無しさん
2018/10/02(火) 07:14:31.94ID:+JdY6jxX あとこれも
構造化例外処理と UnhandledExceptionFilter
https://www.keicode.com/windows/windows_exception_handling.php
構造化例外処理と UnhandledExceptionFilter
https://www.keicode.com/windows/windows_exception_handling.php
358デフォルトの名無しさん
2018/10/02(火) 07:41:02.78ID:+JdY6jxX359デフォルトの名無しさん
2018/10/02(火) 08:43:48.77ID:+JdY6jxX ただ、例外のハンドリングはできても、処理を続行するのは難しいね
EXCEPTION_CONTINUE_EXECUTION を返すと処理は続行されるけど
例外が発生するところから続行されるからね
例外が発生したところの次の命令から続行されるわけじゃないからね
EXCEPTION_CONTINUE_EXECUTION を返すと処理は続行されるけど
例外が発生するところから続行されるからね
例外が発生したところの次の命令から続行されるわけじゃないからね
360デフォルトの名無しさん
2018/10/02(火) 14:17:43.67ID:kh21zWRr >>359
次の命令からでも、続行する方法あるよ。
次の命令からでも、続行する方法あるよ。
361デフォルトの名無しさん
2018/10/02(火) 18:27:14.93ID:6jgE/r0r アセンブラが難しすぎて読めません
https://gyazo.com/ba3099329df9872df87fa3c35ff13384
これはFPSの弾数周辺のアセンブリなんですが、どういう処理をしてるのか全く分かりません
どういう風に読んでいけば理解できるのか?ヒント下さい
ニーモニックは何となく分かるんですけど・・
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がいる理由の一つです)
呼び出し元のコードに細工をすれば例外なんてめんどくさい物を使わずにすみますが、エミュレートしないケースの
オーバーヘッドを完全になくせるか心配です。コンパイラの最適化でインライン展開とデッドコード削除が約束されるなら
そっちの方が遙かに楽ですが・・・
例外ハンドラでメモリを確保してしまうと2回目以降や隣接するアドレスのアクセス時に例外が発生しなくなってしまうので避けたいです
あとWindowsで>>334をやろうとした場合0x00001000から8Byteをあける必要がありますが、そのアドレスへデータをロードしないよう
MSVCのリンカへ指示する方法がわかりません
ldやlldなどであればリンカスクリプトで指示できるらしいのですが・・・(OSの候補にLinuxやFreeBSDがいる理由の一つです)
呼び出し元のコードに細工をすれば例外なんてめんどくさい物を使わずにすみますが、エミュレートしないケースの
オーバーヘッドを完全になくせるか心配です。コンパイラの最適化でインライン展開とデッドコード削除が約束されるなら
そっちの方が遙かに楽ですが・・・
363デフォルトの名無しさん
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 バイト以外の部分もアクセス禁止になるので、その部分でも、例外ハンドラ
が起動してしまうので、その部分についての処理も例外ハンドラに書くようにする。
例外機構を使わずに、以下のような方法も場合によっては使える:
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に寄せた可能性も微レ存)
日本車に使われてるらしいし、自動車は国の基幹産業だし(つまりルネサスのお得意様は日本の自動車メーカー)、あり得なくはない。
x86とZ80を合わせたようなニーモニックだけかと思ったらAをR0、XをR1って別名に出来たりAXがRP0に出来たり、GR0、GR1って書くCASLUにニーモニックが似てるんだが。。。
これってもしかして癒着とかじゃあるまいな。
(逆にルネサスがCASLUに寄せた可能性も微レ存)
日本車に使われてるらしいし、自動車は国の基幹産業だし(つまりルネサスのお得意様は日本の自動車メーカー)、あり得なくはない。
365デフォルトの名無しさん
2018/10/22(月) 19:56:28.08ID:u6NjsIb0 仮想アセンブラでは、LLVM が標準
366デフォルトの名無しさん
2018/10/23(火) 14:50:58.07ID:yFsvvFWj 病院逝け
367デフォルトの名無しさん
2018/10/23(火) 18:22:26.97ID:J6rCDaEz もう少し髪が伸びたらな
368デフォルトの名無しさん
2018/11/26(月) 21:11:44.08ID:gUboiJHI LLVMネタってここで良いんですかね?
369デフォルトの名無しさん
2018/11/30(金) 09:46:12.16ID:+k7v6spR アセンブラの勉強始めていきなり躓いてるのですが、オペランドの記述で
r/m32やimm32やr32やm32って何の略なんですか?
検索しても命令一覧表ばかり引っかかって・・(;´д`)
r/m32やimm32やr32やm32って何の略なんですか?
検索しても命令一覧表ばかり引っかかって・・(;´д`)
370デフォルトの名無しさん
2018/11/30(金) 10:47:42.01ID:FCMY8z7v r32: 32bit幅レジスタ
m32: 32bit幅メモリ
imm32: 32bit幅即値
m32: 32bit幅メモリ
imm32: 32bit幅即値
371デフォルトの名無しさん
2018/11/30(金) 10:53:47.90ID:HF1f08kq 命令の内部フォーマットとアドレッシングモード
https://www.mztn.org/lxasm64/amd05.html
https://www.mztn.org/lxasm64/amd05.html
372デフォルトの名無しさん
2018/11/30(金) 15:33:43.72ID:m3TSK4YL >>367
オシャレ
オシャレ
373デフォルトの名無しさん
2018/11/30(金) 17:07:23.34ID:W1b9qzPZ >>368
知ってても答えたくないかも。
知ってても答えたくないかも。
374デフォルトの名無しさん
2018/11/30(金) 17:26:55.55ID:u043vODt >>365
あれは人間が読むコードじゃない
あれは人間が読むコードじゃない
376デフォルトの名無しさん
2018/12/02(日) 13:54:11.82ID:vFBVENFT LLVM 豆知識。
getelementptr には、似て非なるものが二種類ある。命令タイプと、定数タイプ。
後者は、他の命令のオペランドで用い、括弧でくくるような書き方をする。
仮想レジスタ %n に、整数定数を代入する命令が無い。
それで困った場合は、
%10 = add i32 定数値, 0
などとすると良い。同様にポインタ定数も直接は代入できないが、
%10 = getelementptr TYPE, TYPE * アドレス定数, 0
などとすれbな代入できる。
getelementptr には、似て非なるものが二種類ある。命令タイプと、定数タイプ。
後者は、他の命令のオペランドで用い、括弧でくくるような書き方をする。
仮想レジスタ %n に、整数定数を代入する命令が無い。
それで困った場合は、
%10 = add i32 定数値, 0
などとすると良い。同様にポインタ定数も直接は代入できないが、
%10 = getelementptr TYPE, TYPE * アドレス定数, 0
などとすれbな代入できる。
377デフォルトの名無しさん
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) とは全く無関係の
バイト単位のオフセット値を指定できる。
【命令タイプ】
%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) とは全く無関係の
バイト単位のオフセット値を指定できる。
378デフォルトの名無しさん
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]);
と同じ。覚えておくことは、アドレス演算子「&」が、最後にだけ付くということ。
この規則は構造体が中に含まれている場合でも全く変わらない。
【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]);
と同じ。覚えておくことは、アドレス演算子「&」が、最後にだけ付くということ。
この規則は構造体が中に含まれている場合でも全く変わらない。
379デフォルトの名無しさん
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
となる。
規則性は、よく考えると分かる。
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
となる。
規則性は、よく考えると分かる。
380デフォルトの名無しさん
2018/12/02(日) 14:27:39.98ID:vFBVENFT >>378
誤: TYPE ptr;
正: TYPE *ptr;
誤: TYPE ptr;
正: TYPE *ptr;
381デフォルトの名無しさん
2018/12/08(土) 22:09:51.24ID:NuFUG+1u LLVMのフロントエンドとバックエンドの自由度は極めて高い。CPUどころかGPUまである
ということはアーキテクチャAの実行イメージを入力に、アーキテクチャBの実行イメージを出力することも出来そう
と妄想した
ということはアーキテクチャAの実行イメージを入力に、アーキテクチャBの実行イメージを出力することも出来そう
と妄想した
382デフォルトの名無しさん
2018/12/11(火) 15:12:16.55ID:TeIOtXwo >>381
・Windows の EXE の場合、IAT、ILT、THUNK、DLL の名前解決などの LLVM への
置き換えが果たして可能かどうか。これに関してはもしかしたら難しいかもしれない。
・COFF EXE の場合は可能かもしれないが、データ領域とコード領域を絶対に間違いなく
区別する必要も有る。
・Windows の EXE の場合、IAT、ILT、THUNK、DLL の名前解決などの LLVM への
置き換えが果たして可能かどうか。これに関してはもしかしたら難しいかもしれない。
・COFF EXE の場合は可能かもしれないが、データ領域とコード領域を絶対に間違いなく
区別する必要も有る。
383381
2018/12/11(火) 17:56:58.27ID:8tcWxISv >>382
そういう動的な処理の多いシステムは難易度が高いと思うので、ゲーム機のROMイメージを別のプラットフォームで
実行できる実行イメージに出来ないかなと思った。一般的なエミュレータより高効率で動作させられるはず
と妄想した
そういう動的な処理の多いシステムは難易度が高いと思うので、ゲーム機のROMイメージを別のプラットフォームで
実行できる実行イメージに出来ないかなと思った。一般的なエミュレータより高効率で動作させられるはず
と妄想した
384遠隔 MIPS フラッシュ書き込みテスト実験中
2019/02/23(土) 13:51:34.34ID:RfpPY2e5 MIPS アセンブラ初心者なんだけどおせーて?
asm volatile (“di %0” :“=r” (status));
って 割り込みを拒否して さらにstatusに現在の割り込み設定を退避させてるって意味でええの?
asm volatile (“di %0” :“=r” (status));
って 割り込みを拒否して さらにstatusに現在の割り込み設定を退避させてるって意味でええの?
385デフォルトの名無しさん
2019/02/24(日) 09:52:41.67ID:pcDSz9Pr386デフォルトの名無しさん
2019/02/24(日) 09:54:36.33ID:pcDSz9Pr 誤:6804
正:6809
多分、日本のパソコン文化の主流は、8080, Z80, 8086, 80386(IA32) だったと
思う。書くと反感買うと思うけど、少数派として、6809, 68000 があった、
という認識。
正:6809
多分、日本のパソコン文化の主流は、8080, Z80, 8086, 80386(IA32) だったと
思う。書くと反感買うと思うけど、少数派として、6809, 68000 があった、
という認識。
387デフォルトの名無しさん
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++390デフォルトの名無しさん
2019/02/24(日) 14:42:53.37ID:/sgxXPqq 日本でMIPSだとプレステが有名だが・・・
391デフォルトの名無しさん
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です
_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 などが
生じると思われる。
ここまでは全て記憶と直感に頼って書いた。
直感からすると、原因は、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 などが
生じると思われる。
ここまでは全て記憶と直感に頼って書いた。
394デフォルトの名無しさん
2019/02/27(水) 16:18:53.04ID:N0K9USfO 誤: リンク時に entry point を指定していよう
正: リンク時に entry point を指定しないよう
すまないが、あなたの書き込みの全部は読んでおらず、最初の方の
数行を見ての直感で答えた。
正: リンク時に entry point を指定しないよう
すまないが、あなたの書き込みの全部は読んでおらず、最初の方の
数行を見ての直感で答えた。
395デフォルトの名無しさん
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 は行ってはならない。
すまん。
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 みたいな値になっているかもしれない。
「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
などのようになる場合など、さまざま。それが正しくなっているかの確認も必要。
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
などのようになる場合など、さまざま。それが正しくなっているかの確認も必要。
398デフォルトの名無しさん
2019/07/04(木) 19:46:17.60ID:JhnD4djU 今時のIA32コードを吐く処理系がよく使う命令についてのまとめた資料ってないですかね
486DXあたりでもかなりの命令数になりますが現行で使われている命令は限定されますよね?
486DXあたりでもかなりの命令数になりますが現行で使われている命令は限定されますよね?
399デフォルトの名無しさん
2019/07/05(金) 11:29:01.09ID:SLYFNUzn >現行で使われている命令は限定
何言ってんだ
何言ってんだ
400デフォルトの名無しさん
2019/07/05(金) 19:14:34.33ID:lm712Ojq x86系は現行のアーキテクチャとしては間違いなくカオス組。解析器とか作りたくねー
401デフォルトの名無しさん
2019/07/21(日) 02:41:27.70ID:jI92lOqS intelで公開している奴じゃなくて?
402デフォルトの名無しさん
2019/10/06(日) 15:58:10.24ID:xhkeezXX x86 の条件付きジャンプ命令
JG Greater
JL Less
JE Equal
JNE Not Equal
は分かったのですが、
JA
JB
は何の英単語の略なんでしょうか?
JG Greater
JL Less
JE Equal
JNE Not Equal
は分かったのですが、
JA
JB
は何の英単語の略なんでしょうか?
403デフォルトの名無しさん
2019/10/06(日) 16:06:45.50ID:wxDvIEUu aboveとbelowだったかな
404デフォルトの名無しさん
2019/10/06(日) 17:14:52.78ID:xhkeezXX おお、なるほど!
素早いご回答ありがとうございます
素早いご回答ありがとうございます
405デフォルトの名無しさん
2019/10/06(日) 17:29:21.50ID:xhkeezXX406デフォルトの名無しさん
2019/10/06(日) 17:30:39.06ID:pvG0vkV+ 昔は常識だった
407デフォルトの名無しさん
2019/10/21(月) 09:51:46.99ID:J3DzZudC アセンブラ買ったらリファレンス一冊ついてたしな...
今ならintelのpdf先に見る所?
今ならintelのpdf先に見る所?
408デフォルトの名無しさん
2019/10/24(木) 10:43:50.55ID:AtkMQyN4 古いのなら日本語マニュアルあるぞ
インテルエクステンデッド・メモリ64テクノロジ・ソフトウェア・デベロッパーズ・ガイド第1巻
インテルRエクステンデッド・メモリ64テクノロジ・ソフトウェア・デベロッパーズ・ガイド第2巻
直リンクはちょくりんNGで貼れないのでググッて
インテルエクステンデッド・メモリ64テクノロジ・ソフトウェア・デベロッパーズ・ガイド第1巻
インテルRエクステンデッド・メモリ64テクノロジ・ソフトウェア・デベロッパーズ・ガイド第2巻
直リンクはちょくりんNGで貼れないのでググッて
409デフォルトの名無しさん
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
全部全角にしてみた
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
どうみてもこれで充分です
ほんとうにありがとうございました
EM64T_VOL2_30083502_i.pdf
どうみてもこれで充分です
ほんとうにありがとうございました
411デフォルトの名無しさん
2019/10/24(木) 11:12:11.26ID:AtkMQyN4412デフォルトの名無しさん
2019/10/25(金) 15:41:34.61ID:4V9sCl2t >>406
8086のアセンブラと言えば、PC-9801とBASICやMS-DOSの組み合わせだが、
当時パソコンを持っていた人はBASICは知っている人が多く、C言語は
好き物が理解していたが、アセンブラまで理解している人は稀で、
ja の a が above であることを知っている人はごく一部だった。
8086のアセンブラと言えば、PC-9801とBASICやMS-DOSの組み合わせだが、
当時パソコンを持っていた人はBASICは知っている人が多く、C言語は
好き物が理解していたが、アセンブラまで理解している人は稀で、
ja の a が above であることを知っている人はごく一部だった。
413デフォルトの名無しさん
2019/10/25(金) 16:36:39.41ID:BNTJ335Q >アセンブラまで理解している人は稀
あほすぎ
お前のまわりがそうだっただけだろ
あほすぎ
お前のまわりがそうだっただけだろ
414デフォルトの名無しさん
2019/10/25(金) 17:38:11.71ID:UlVp4BAq >>412
当時、The BASICやASCIIでBASICとアセンブラで組んだゲームが山ほど掲載されてた。
同じことをしたいと思ったら8086のアセンブラ知らないとどうしようもなかったんだよ。
BASICはエラー出しても止まってくれたけど、アセンブラでエラー出すとそのままマシンが固まったり
勝手にリブートしたりして何度も泣いたもんだ。けど同時に非常に面白かった。
アセンブラで「どこか1カ所でもミスったらマシンが飛ぶ」と思ったら緊張感がハンパない。
「これで絶対動く」という確信が持てるまで何度も見直してから、震える指でエンターキーを押して
動いたときの感動。立ち上がって全身でガッツポーズしたね。
プログラミングの醍醐味はこれだよ。これ覚えたらもう止められない。
当時、The BASICやASCIIでBASICとアセンブラで組んだゲームが山ほど掲載されてた。
同じことをしたいと思ったら8086のアセンブラ知らないとどうしようもなかったんだよ。
BASICはエラー出しても止まってくれたけど、アセンブラでエラー出すとそのままマシンが固まったり
勝手にリブートしたりして何度も泣いたもんだ。けど同時に非常に面白かった。
アセンブラで「どこか1カ所でもミスったらマシンが飛ぶ」と思ったら緊張感がハンパない。
「これで絶対動く」という確信が持てるまで何度も見直してから、震える指でエンターキーを押して
動いたときの感動。立ち上がって全身でガッツポーズしたね。
プログラミングの醍醐味はこれだよ。これ覚えたらもう止められない。
415デフォルトの名無しさん
2019/10/25(金) 18:16:12.88ID:4V9sCl2t 俺自身はアセンブラは使ってたよ。
しかし、一般的にはそんなに使われている訳ではなかった。
プロのゲームプログラマやそういう雑誌に掲載されたゲーム作者は使っていたが。
そういう人たちは特殊だったので、天才プログラマなんて言葉が生まれた。
しかし、一般的にはそんなに使われている訳ではなかった。
プロのゲームプログラマやそういう雑誌に掲載されたゲーム作者は使っていたが。
そういう人たちは特殊だったので、天才プログラマなんて言葉が生まれた。
416デフォルトの名無しさん
2019/10/25(金) 18:21:42.17ID:4V9sCl2t417デフォルトの名無しさん
2019/10/25(金) 21:14:38.60ID:UlVp4BAq >>416
誰でもやってたなんて言ってないんだが。やってた人もけっこういたって程度だろう。
もっと正確に言うなら、当時プログラムをやってた人の総数と、そのうちアセンブラをやってた人が何割いたか
という統計データでも探してこないと正確な割合は出ない。
ただ、そういう本が何冊も出てたってことはそれだけ売れてたってことだから、程度の差はあれ、
アセンブラに興味があった人がそれなりにいたことは間違いない。
誰でもやってたなんて言ってないんだが。やってた人もけっこういたって程度だろう。
もっと正確に言うなら、当時プログラムをやってた人の総数と、そのうちアセンブラをやってた人が何割いたか
という統計データでも探してこないと正確な割合は出ない。
ただ、そういう本が何冊も出てたってことはそれだけ売れてたってことだから、程度の差はあれ、
アセンブラに興味があった人がそれなりにいたことは間違いない。
418デフォルトの名無しさん
2019/10/25(金) 23:59:54.86ID:tDdAcA6n >>417
ja の a が above の意味であることは知っていても、ja が直前の cmp 命令と
組み合わせて使うことや、グラフィックを描くにはG-VRAMと呼ばれる場所に
数値を書くということまでちゃんと理解できた人が少なかった。
ja の a が above の意味であることは知っていても、ja が直前の cmp 命令と
組み合わせて使うことや、グラフィックを描くにはG-VRAMと呼ばれる場所に
数値を書くということまでちゃんと理解できた人が少なかった。
419デフォルトの名無しさん
2019/10/26(土) 02:40:13.17ID:gJ3xyH9v >>418
PC雑誌、アセンブラのドキュメントと初級解説本、9801の解析本くらい読めば普通に書いてあった。
PC雑誌、アセンブラのドキュメントと初級解説本、9801の解析本くらい読めば普通に書いてあった。
420デフォルトの名無しさん
2019/10/26(土) 02:52:45.09ID:dcsgYCXg >>419
今現在、プログラミングしている人の大部分は、スクリプト言語しか使えない
と言われている。その理由は、ポインタが理解できないから。
ポインタが理解出来ない人は、アセンブラの間接参照 [reg + addr]
も理解できないだろうから、アセンブラではグラフィックもまともに描けない。
当時の常識といっても、今のパソコン使いが当時にタイムスリップしても
大半はアセンブラを理解はおろか使いこなすなど出来ない。
今現在、プログラミングしている人の大部分は、スクリプト言語しか使えない
と言われている。その理由は、ポインタが理解できないから。
ポインタが理解出来ない人は、アセンブラの間接参照 [reg + addr]
も理解できないだろうから、アセンブラではグラフィックもまともに描けない。
当時の常識といっても、今のパソコン使いが当時にタイムスリップしても
大半はアセンブラを理解はおろか使いこなすなど出来ない。
421デフォルトの名無しさん
2019/10/26(土) 09:59:09.07ID:e6NVGnmw422デフォルトの名無しさん
2019/10/26(土) 18:30:52.81ID:gJ3xyH9v >>420
一般の人はアセンブラなんて見たこともないだろうから別にそれはそれでいい。
プログラマーだってアセンブラが使いにくいからC使ってるわけだし。
ただ、アセンブラやっとくとCPUの動作が直にわかるし、簡単なプログラムでも超高速に動く。
Cからアセンブラコードを生成して、内部でどんな処理してるか調べることもできる。
そういうところが面白いと思う人がやればいいんだよ。
一般の人はアセンブラなんて見たこともないだろうから別にそれはそれでいい。
プログラマーだってアセンブラが使いにくいからC使ってるわけだし。
ただ、アセンブラやっとくとCPUの動作が直にわかるし、簡単なプログラムでも超高速に動く。
Cからアセンブラコードを生成して、内部でどんな処理してるか調べることもできる。
そういうところが面白いと思う人がやればいいんだよ。
423デフォルトの名無しさん
2019/10/26(土) 22:35:07.76ID:3WWCBV2x CASL2の話題はこのスレでしていいですか?
424デフォルトの名無しさん
2019/10/27(日) 02:06:55.94ID:LkxSYXiy 上の流れ見るに90年代が華の野郎共の巣だから2はわかんないかも(笑
426デフォルトの名無しさん
2019/10/27(日) 11:40:07.17ID:CbvQpcn+ 試験科目LLVMにすれば良いのに
427デフォルトの名無しさん
2019/10/27(日) 12:56:27.43ID:duBk5x4n 普通にゲームしかやらんやつの方が多かっただけで
できるやつが少ないかったのは事実
できるやつが少ないかったのは事実
428デフォルトの名無しさん
2019/10/27(日) 17:04:26.06ID:GpjOYffU >>427
比率で言えば大体黄金比(2:6:2)になる。昔も今もプログラマーで本当にできるのは上位2割、
全く向いてないのが下の2割、まあまあ普通なのが真ん中の6割。
スクリプトしか書けないのはこの6割の中に入る。上位2割はスクリプトなんてちょっとやればわかるから
何とも思ってない。文字通りレベルが違うから話も合わない。でもそれでいいんだよ。
比率で言えば大体黄金比(2:6:2)になる。昔も今もプログラマーで本当にできるのは上位2割、
全く向いてないのが下の2割、まあまあ普通なのが真ん中の6割。
スクリプトしか書けないのはこの6割の中に入る。上位2割はスクリプトなんてちょっとやればわかるから
何とも思ってない。文字通りレベルが違うから話も合わない。でもそれでいいんだよ。
429デフォルトの名無しさん
2019/10/27(日) 17:50:07.64ID:9Kmf+J9a 最も利用率が高いのはRubyだが
マイコン相手にすればアセンブラとにらめっこだし
気に入らないが必要とあればC/C++やPythonやJavaScriptも触る
マイコン相手にすればアセンブラとにらめっこだし
気に入らないが必要とあればC/C++やPythonやJavaScriptも触る
430デフォルトの名無しさん
2019/10/28(月) 09:34:47.25ID:SaUE9md3 80年代はアセンブラ関連の書籍がたくさんあった
Z80、6809、8086、68000
まだ1989年頃まではCコンパイラが高価だったりして敷居が高かったし
BASICやってた人は高速化するにはマシン語を使ってたしな
アセンブラやマシン語初心者向けのBASICから使えるマシン語の本もたくさん出てた
アセンブラやマシン語を使ってゲームを作る本とかな
電子工作関連でもZ80のアセンブラや周辺LSIのプログラミングで初心者向けの本がたくさんあった
アセンブラ覚えるなら1980年代や1990年代初め頃の方がずっと恵まれてたな
図書館の蔵書とか検索してみるとそういう古い本が出てくるかもよ
Z80、6809、8086、68000
まだ1989年頃まではCコンパイラが高価だったりして敷居が高かったし
BASICやってた人は高速化するにはマシン語を使ってたしな
アセンブラやマシン語初心者向けのBASICから使えるマシン語の本もたくさん出てた
アセンブラやマシン語を使ってゲームを作る本とかな
電子工作関連でもZ80のアセンブラや周辺LSIのプログラミングで初心者向けの本がたくさんあった
アセンブラ覚えるなら1980年代や1990年代初め頃の方がずっと恵まれてたな
図書館の蔵書とか検索してみるとそういう古い本が出てくるかもよ
431デフォルトの名無しさん
2019/10/28(月) 09:46:48.07ID:SaUE9md3 今と違って1980年代中ごろまではBASICがメインだったし
ゲームしかやらない人を除けば1980年中ごろまでのパソコンユーザは
プログラミングができるのが当たり前だった
だからパソコンユーザの中でアセンブラもやってた人は多かったよ
そもそもパソコンを扱える人自体が今と違って少なかった
プログラミングに興味がない人はそもそもパソコンにも興味がなかったからな
ゲームしかやらない人を除けば1980年中ごろまでのパソコンユーザは
プログラミングができるのが当たり前だった
だからパソコンユーザの中でアセンブラもやってた人は多かったよ
そもそもパソコンを扱える人自体が今と違って少なかった
プログラミングに興味がない人はそもそもパソコンにも興味がなかったからな
432デフォルトの名無しさん
2019/10/28(月) 09:58:42.55ID:SaUE9md3 >>416
当時はパソコンを趣味としてやってる人自体が少なかった
パソコンに興味のない普通の人はキーボードなんて叩いて何が面白いのとかそういう認識
パソコンなんてわけのわからないそんなつまらないものなんでやってるのって感じ
そういう感じなんでパソコンユーザは根暗とかオタクとか言われて馬鹿にされてたからな
当時はパソコンを趣味としてやってる人自体が少なかった
パソコンに興味のない普通の人はキーボードなんて叩いて何が面白いのとかそういう認識
パソコンなんてわけのわからないそんなつまらないものなんでやってるのって感じ
そういう感じなんでパソコンユーザは根暗とかオタクとか言われて馬鹿にされてたからな
433デフォルトの名無しさん
2019/10/28(月) 10:04:22.32ID:SaUE9md3 >>427
そのゲームが一番アセンブラやマシン語を必要としてたんだよな
当時、雑誌にゲームを投稿してた人のインタビュー
https://akiba-pc.watch.impress.co.jp/docs/sp/1213044.html
そのゲームが一番アセンブラやマシン語を必要としてたんだよな
当時、雑誌にゲームを投稿してた人のインタビュー
https://akiba-pc.watch.impress.co.jp/docs/sp/1213044.html
434デフォルトの名無しさん
2019/10/28(月) 10:06:00.01ID:SaUE9md3 マシン語 ゲーム
この2つのキーワードで検索してみると80年代のアセンブラやマシン語の本がたくさん出てくる
この2つのキーワードで検索してみると80年代のアセンブラやマシン語の本がたくさん出てくる
435デフォルトの名無しさん
2019/10/28(月) 15:42:16.95ID:CizzAz3Z >ゲームしかやらんやつの
ゲームで遊んでた人と
ゲームを造ってた人を
意図的に混同してるだろ
しかもそもそもマ板の話題だし
ム板でするな
ゲームで遊んでた人と
ゲームを造ってた人を
意図的に混同してるだろ
しかもそもそもマ板の話題だし
ム板でするな
436デフォルトの名無しさん
2019/10/28(月) 15:55:47.51ID:jVNnMdKT >>431
アセンブラは、本を買ってみたりした人は多かったかもしれないが、
実際に使いこなすまでにいたった人は稀だったはず。
だから、アセンブラやマシン語は難しいという認識だった。
なお、ちょっと話がずれるが、LLVM は、型の部分が煩雑で普通のアセンブラよりも
難しい部分がある。
構造体型を使わなければ普通のアセンブラと同じように出来ないことは
ないが、それでも、bitcast などを頻繁に繰り返す必要がある。
なお、構造体型をヒントに最適化している可能性があるので、面倒でも
構造体型を使う必要があるかもしれない。
上手く整理して理解しないと、コンパイラを作る人泣かせになる。
アセンブラは、本を買ってみたりした人は多かったかもしれないが、
実際に使いこなすまでにいたった人は稀だったはず。
だから、アセンブラやマシン語は難しいという認識だった。
なお、ちょっと話がずれるが、LLVM は、型の部分が煩雑で普通のアセンブラよりも
難しい部分がある。
構造体型を使わなければ普通のアセンブラと同じように出来ないことは
ないが、それでも、bitcast などを頻繁に繰り返す必要がある。
なお、構造体型をヒントに最適化している可能性があるので、面倒でも
構造体型を使う必要があるかもしれない。
上手く整理して理解しないと、コンパイラを作る人泣かせになる。
437デフォルトの名無しさん
2019/10/28(月) 19:16:09.04ID:jHTeibRQ 80年代後半だが電子系の学生なら講義でZ80のアセンブラやらされてな
438デフォルトの名無しさん
2019/10/28(月) 21:16:27.78ID:6rYZFXXL RAM640KBでCとかほぼ無理だろ
X68000でも4MB以上推奨だった記憶
X68000でも4MB以上推奨だった記憶
>>430
書籍もそうだが、i486 の時代になっても ms-dos が動き、プロテクトモードは自由に触り放題、というのが当時はすばらしかった
今はプロテクトモードは触らしてもらえない、マシン語化する価値があるものは、キャリーフラグを触れば速くなるもの、くらいしか思いつかない
書籍もそうだが、i486 の時代になっても ms-dos が動き、プロテクトモードは自由に触り放題、というのが当時はすばらしかった
今はプロテクトモードは触らしてもらえない、マシン語化する価値があるものは、キャリーフラグを触れば速くなるもの、くらいしか思いつかない
440デフォルトの名無しさん
2019/10/29(火) 01:38:16.40ID:axC2qBNh441デフォルトの名無しさん
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ビットコンパイラ
では無理だった。
>今はプロテクトモードは触らしてもらえない、
最初からOSがプロテクトモードにしてくれている。
MS-DOSで自力でプロテクトモードにするのはかなり大変だったのでずっと
楽になってる。というのは、プロテクトモードにした場合、DOS
は、仮想8086モードで動かさないといけなかった。しかし、そうするためには
非常に膨大なプログラミングが必要になった。仮想8086モードは、設定すれば
すぐ動くわけではなく、割り込みテーブルなどを全部自分で用意しなければ
ならなかったから。割り込みテーブルもテーブルを用意すれば終わりではなく、
ほとんどエミュレータの作成をしてる感じで、32BITプログラムを用意して、
16BITコードでsti,cliやint命令なんかが実行されるたびに、エミュレーション
ハンドらが起動されて、そこでしかるべき処理を行う必要があった。
だから、自力でDOSをプロテクトモードにするのはほとんど不可能で、
DPMIやVCPIという既存のプログラムが利用された。
しかし、それらをまともにつかうのは、TURBO C++などの16ビットコンパイラ
では無理だった。
442デフォルトの名無しさん
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
をわざと変な風に設計したのではないかと疑っている。
一般の人は、そんな裏事情を知らない。
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
をわざと変な風に設計したのではないかと疑っている。
一般の人は、そんな裏事情を知らない。
443デフォルトの名無しさん
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はあまり普及はしなかったが
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はあまり普及はしなかったが
444デフォルトの名無しさん
2019/10/29(火) 07:09:00.71ID:Zl5vhLEl DJCPPじゃなくてDJGPPだった
445デフォルトの名無しさん
2019/10/29(火) 07:24:26.40ID:Zl5vhLEl アセンブラに話を戻すと
DOSエクステンダーのEXE386はMASMの5.0以上やTurboAssemblerなどのアセンブラで
EXE386上で動作するアプリを作れた
プロテクトモード上の特定のアドレスにVRAMがマッピングされていたので
VRAMへのアクセスも容易だったな
そのEXE386は今でもベクターからダウンロードできる
DOSエクステンダーのEXE386はMASMの5.0以上やTurboAssemblerなどのアセンブラで
EXE386上で動作するアプリを作れた
プロテクトモード上の特定のアドレスにVRAMがマッピングされていたので
VRAMへのアクセスも容易だったな
そのEXE386は今でもベクターからダウンロードできる
446デフォルトの名無しさん
2019/10/29(火) 17:54:53.05ID:VnX4qZP9 >>445
当時、ほとんどのアプリは基本ロジック部分はC/C++言語で書いていて、
グラフィックなどの速度が必要な部分をアセンブラで書くということをやっていた。
だから確かにアセンブラからは32BITアドレッシングは可能であっても、
C/C++が使えなければ現実的に使うことは無理であった。
だから、何らかのC/C++コンパイラが必要となった。それが結構高価であった
ことと、既にWin95に一般民が移行していたので選択の余地は狭かった。
ただし、移行というより、1995はパソコン元年などといわれたくらい、
初めてパソコンを使い始める大挙して押し寄せた。
だから、DOSエクステンダは魅力的ではあっても、その流れに逆らうことは
難しかった。
当時、ほとんどのアプリは基本ロジック部分はC/C++言語で書いていて、
グラフィックなどの速度が必要な部分をアセンブラで書くということをやっていた。
だから確かにアセンブラからは32BITアドレッシングは可能であっても、
C/C++が使えなければ現実的に使うことは無理であった。
だから、何らかのC/C++コンパイラが必要となった。それが結構高価であった
ことと、既にWin95に一般民が移行していたので選択の余地は狭かった。
ただし、移行というより、1995はパソコン元年などといわれたくらい、
初めてパソコンを使い始める大挙して押し寄せた。
だから、DOSエクステンダは魅力的ではあっても、その流れに逆らうことは
難しかった。
447デフォルトの名無しさん
2019/10/29(火) 18:03:50.25ID:I2MyCbhZ 俺の質問めっちゃ低レベル…
LDやSTなどの命令やオペランドは主記憶に記憶されることは分かったんですが、
コメントも同様に、オペランドとかの後に記憶されているんですか?
LDやSTなどの命令やオペランドは主記憶に記憶されることは分かったんですが、
コメントも同様に、オペランドとかの後に記憶されているんですか?
448デフォルトの名無しさん
2019/10/29(火) 18:11:29.42ID:n7hbVS5F >>447
一般的な処理系ならコメントはアセンブル時に削除される
一般的な処理系ならコメントはアセンブル時に削除される
449デフォルトの名無しさん
2019/10/29(火) 18:48:08.61ID:ex5BLs+R 今でもはじめて読む8086読んどけかと思えば絶版なのかな...amazon在庫無いね
>>441
>プロテクトモードにした場合、DOSは、仮想8086モードで動かさないといけなかった。
いいえ、リアルモードで DOS を起動して、ユーザープログラムが勝手にプロテクトモードに変更してなんら問題ないですよ
プロテクトモードから一時的にリアルモードに戻ることはできませんが、プロテクトモードで割り込みテーブルを再設定すれば問題ないですね
>自力でDOSをプロテクトモードにするのはほとんど不可能で、DPMIやVCPIという既存のプログラムが利用された。
まあそれは事実ですが、あと DOS エクステンダーがよく使われましたね
>プロテクトモードにした場合、DOSは、仮想8086モードで動かさないといけなかった。
いいえ、リアルモードで DOS を起動して、ユーザープログラムが勝手にプロテクトモードに変更してなんら問題ないですよ
プロテクトモードから一時的にリアルモードに戻ることはできませんが、プロテクトモードで割り込みテーブルを再設定すれば問題ないですね
>自力でDOSをプロテクトモードにするのはほとんど不可能で、DPMIやVCPIという既存のプログラムが利用された。
まあそれは事実ですが、あと DOS エクステンダーがよく使われましたね
>>442
>既に、EMSメモリを使うために、プロテクトモードは使われてしまっており、
>DOSは仮想8086モードで動いていた。そのせいで、自作プログラムで勝手に
>プロテクトモードをコントロールすることは不可能だった。
EMS なんて非常に使いにくいものはさっさと追放しちゃえばよかったのですよ
>既に、EMSメモリを使うために、プロテクトモードは使われてしまっており、
>DOSは仮想8086モードで動いていた。そのせいで、自作プログラムで勝手に
>プロテクトモードをコントロールすることは不可能だった。
EMS なんて非常に使いにくいものはさっさと追放しちゃえばよかったのですよ
453デフォルトの名無しさん
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にも対応するとなると、かなり面倒くさかっただろうとは思う
80286ではプロテクトモードからリアルモードに戻ることが出来なかったため
戻るために特殊な仕組みが必要になり、プロテクトモードが非常に使いにくかった
386以降は、単純にリアルモードに戻ることが可能になったため使いやすくなり
セグメントのリミットを設定し直してそのまま戻ることで
リアルモード(DOS)から4G全てにアクセスすることも出来るようになった
そして、仮想86モードでの割り込み処理も、別に複雑な処理などは基本的には必要ない
なぜならBIOSにある、元の割り込み処理ルーチンに処理させれば良いだけだから
もちろんIDTをセットアップして処理するプログラムは用意する必要はあるが
大半はスタックにあるリアルモードでの戻り番地等を設定して、
あたかもリアルモードで割り込みが起こったかのようにBIOSやDOSの割り込みベクタテーブルのアドレスに飛ぶだけ
自前で処理する必要があるのは、GPフォルトやページフォルト、
それにA20の操作の処理が入ったらページテーブルを書き換える等するだけ
その程度でも、HMA64KやUMBを用意して空きメモリに余裕があるDOSを動かすくらいなら出来た
(ただし、DMAにも対処するにはまた別途処理が必要)
もちろんEMS等に対応するには、そのための処理ルーチンを用意する必要があるし
EMSやVCPI程度ならともかく、DPMIにも対応するとなると、かなり面倒くさかっただろうとは思う
455デフォルトの名無しさん
2019/10/29(火) 21:10:57.31ID:KWhI3UgV >>449
Amazonに「64ビットアセンブラ入門」というのがある。
Amazonに「64ビットアセンブラ入門」というのがある。
456デフォルトの名無しさん
2019/10/29(火) 21:13:34.56ID:KWhI3UgV457デフォルトの名無しさん
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
プログラムもアセンブラで書く。サンプルプログラムもたくさんある。
DOSのように終わったOSではないので、今のPCにもインストールできる。
Kolibriは初期のMenuetからフォークした32bit OS。Menuetは64bit。
面倒なアドレッシング制限もなく、画面表示も簡単にできる。
日本語にはまだ対応していないので、誰かが日本語化すればユーザが増えるかも。
menuet os
http://www.menuetos.net/
kolibri os
http://kolibrios.org/en/index
458デフォルトの名無しさん
2019/10/29(火) 21:48:10.11ID:VnX4qZP9 >>452
そのプリフィックスは、データ用とアドレス用のものだけど、
データ用の方はどのモードからも普通に使えた。ところが、
アドレス用の方はプロテクトモードでしか使えず、
仮想8086モードでも使用不可能になっていた。
それが、Wintel同盟がDOSを使えなくしてWindowsだけを使えるように
するための策略だったのではないかと疑っている
(そんな風に設計する理由は特に無かったのに。)。
そのプリフィックスは、データ用とアドレス用のものだけど、
データ用の方はどのモードからも普通に使えた。ところが、
アドレス用の方はプロテクトモードでしか使えず、
仮想8086モードでも使用不可能になっていた。
それが、Wintel同盟がDOSを使えなくしてWindowsだけを使えるように
するための策略だったのではないかと疑っている
(そんな風に設計する理由は特に無かったのに。)。
459デフォルトの名無しさん
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モードで全く別の領域を
使う仕組みになっていたので、連続的にすることはできなかったためである。
>そして、仮想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モードで全く別の領域を
使う仕組みになっていたので、連続的にすることはできなかったためである。
460デフォルトの名無しさん
2019/10/29(火) 22:02:17.16ID:VnX4qZP9 >>453
>386以降は、単純にリアルモードに戻ることが可能になったため使いやすくなり
>セグメントのリミットを設定し直してそのまま戻ることで
>リアルモード(DOS)から4G全てにアクセスすることも出来るようになった
ここも、隠れ機能としてそういうものがあると聞いたことがあるが、
多分、ちゃんと公表されていなかったのではないかと思う。
>386以降は、単純にリアルモードに戻ることが可能になったため使いやすくなり
>セグメントのリミットを設定し直してそのまま戻ることで
>リアルモード(DOS)から4G全てにアクセスすることも出来るようになった
ここも、隠れ機能としてそういうものがあると聞いたことがあるが、
多分、ちゃんと公表されていなかったのではないかと思う。
461デフォルトの名無しさん
2019/10/29(火) 22:38:00.70ID:Zl5vhLEl >>452
66、67プレフィックスは使えても64KBを超えるオフセットになると一般保護例外が発生する
もう、誰かが書いてるが一度、プロテクトモードに入ってセグメントリミットを設定しなおして
リアルモードに戻れば一般保護例外は発生しなくなるけど、
他のプロテクトモードを使うソフトを一緒に使ってる場合、不具合が発生する可能性はあった
66、67プレフィックスは使えても64KBを超えるオフセットになると一般保護例外が発生する
もう、誰かが書いてるが一度、プロテクトモードに入ってセグメントリミットを設定しなおして
リアルモードに戻れば一般保護例外は発生しなくなるけど、
他のプロテクトモードを使うソフトを一緒に使ってる場合、不具合が発生する可能性はあった
462デフォルトの名無しさん
2019/10/29(火) 22:40:47.58ID:Zl5vhLEl463デフォルトの名無しさん
2019/10/29(火) 22:46:10.13ID:VnX4qZP9464デフォルトの名無しさん
2019/10/29(火) 22:55:18.61ID:VnX4qZP9 >>463
記憶をたどれば、確か、セグメントリミットを4GBに設定したセグメントエントリ
を持ったGDTテーブルを用意してその先頭アドレスをGDTRに入れた後、
確か、CR0 の BIT をいじった後、far jmpを行うとプロテクトモードに入るが、
far jmpを行わなければ、中途半端な状態になって、4GBアクセスできる
リアルモードになるんだった気がする。だから、その後、far jmpを行うと
モードが切り替わってしまうので、その命令は、アプリが暴走しても
絶対に使っちゃいけない。ただし、リアルモードなのでアプリが暴走すると
OSもつられてこけるので、関係ないっちゃ関係ない。
記憶をたどれば、確か、セグメントリミットを4GBに設定したセグメントエントリ
を持ったGDTテーブルを用意してその先頭アドレスをGDTRに入れた後、
確か、CR0 の BIT をいじった後、far jmpを行うとプロテクトモードに入るが、
far jmpを行わなければ、中途半端な状態になって、4GBアクセスできる
リアルモードになるんだった気がする。だから、その後、far jmpを行うと
モードが切り替わってしまうので、その命令は、アプリが暴走しても
絶対に使っちゃいけない。ただし、リアルモードなのでアプリが暴走すると
OSもつられてこけるので、関係ないっちゃ関係ない。
465デフォルトの名無しさん
2019/10/29(火) 23:31:54.59ID:Zl5vhLEl >>463
386はプロテクトモードからリアルモードに戻ることができる
286は戻れないのでハードウェアでCPUだけリセットして復帰するように作る必要がある
PC/ATやその互換機、PC9801の286マシンにはそういう仕組みがハードウェアで備わってる
386はプロテクトモードからリアルモードに戻ることができる
286は戻れないのでハードウェアでCPUだけリセットして復帰するように作る必要がある
PC/ATやその互換機、PC9801の286マシンにはそういう仕組みがハードウェアで備わってる
466447
2019/10/30(水) 00:23:36.64ID:JIJxpsW5467デフォルトの名無しさん
2019/10/30(水) 02:14:08.40ID:qopAd6nC 割れ厨か
468デフォルトの名無しさん
2019/10/30(水) 06:36:17.87ID:hEWImuUH まず、リアルモードでも仮想86モードでも、
アドレスサイズプリフィックスを使うこと自体ではGPフォルトは発生しない
例えば、lea eax, eax+eax*4 という、5倍する時に使うコードは
仮想86モードでも普通に使える
何度も書いているが、
リアルモードと仮想86モードではセグメントのリミットが64Kに設定されているために
その範囲外にアクセスするとGPフォルトになるというだけなので
一旦セグメントリミットを4Gにしてからリアルモードに戻れば、例外を起こさずに全アドレスにアクセスできる
farジャンプは、パイプラインに残っている命令キューをフラッシュするためのものなので、セグメントリミットとはあまり関係ない
例えば自前で仮想86モードを利用した仮想EMSドライバを書く場合
最初にプロテクトモードに移行してリミットを変え、すぐにリアルモードに戻る
そしてリアルモードのコードで全領域をいろいろセットアップし、それから仮想86モードになってDOSに制御を移すという手法が使えた
仮想86モードでの割り込みハンドラも、仮想86モードでのスタック上にある戻り番地の部分に
割り込みベクタテーブルからの番地を置いて(テーブルにそして保存されているSPも変えて)iretするだけだから
別に難しくない
仮想86中でのiretも何か対処する必要があった気もするけど
いずれにせよGPフォルトのハンドラ内でどんな命令が例外を起こしたか調べる必要があるので、
その内部でiretだったらどうするというテーブルジャンプ対応程度で足りたはず
アドレスサイズプリフィックスを使うこと自体ではGPフォルトは発生しない
例えば、lea eax, eax+eax*4 という、5倍する時に使うコードは
仮想86モードでも普通に使える
何度も書いているが、
リアルモードと仮想86モードではセグメントのリミットが64Kに設定されているために
その範囲外にアクセスするとGPフォルトになるというだけなので
一旦セグメントリミットを4Gにしてからリアルモードに戻れば、例外を起こさずに全アドレスにアクセスできる
farジャンプは、パイプラインに残っている命令キューをフラッシュするためのものなので、セグメントリミットとはあまり関係ない
例えば自前で仮想86モードを利用した仮想EMSドライバを書く場合
最初にプロテクトモードに移行してリミットを変え、すぐにリアルモードに戻る
そしてリアルモードのコードで全領域をいろいろセットアップし、それから仮想86モードになってDOSに制御を移すという手法が使えた
仮想86モードでの割り込みハンドラも、仮想86モードでのスタック上にある戻り番地の部分に
割り込みベクタテーブルからの番地を置いて(テーブルにそして保存されているSPも変えて)iretするだけだから
別に難しくない
仮想86中でのiretも何か対処する必要があった気もするけど
いずれにせよGPフォルトのハンドラ内でどんな命令が例外を起こしたか調べる必要があるので、
その内部でiretだったらどうするというテーブルジャンプ対応程度で足りたはず
469デフォルトの名無しさん
2019/10/30(水) 06:40:30.90ID:hEWImuUH >>464
リアルモードに戻る正式な手順は、「各セグメントのリミットを64Kに設定してからレジスタ(確かcr0だと思ったが)を設定」で
それを4Gに設定したままで戻れば、64Kの制限が解除される
もちろん16bitレジスタは16bitでしかアドレスできないので、32bitレジスタを使う必要がある
リアルモードに戻る正式な手順は、「各セグメントのリミットを64Kに設定してからレジスタ(確かcr0だと思ったが)を設定」で
それを4Gに設定したままで戻れば、64Kの制限が解除される
もちろん16bitレジスタは16bitでしかアドレスできないので、32bitレジスタを使う必要がある
470デフォルトの名無しさん
2019/10/30(水) 09:06:54.09ID:C/RG5q83 >>468
>farジャンプは、パイプラインに残っている命令キューをフラッシュするためのものなので、セグメントリミットとはあまり関係ない
関係大有りです。リアルモードからプロテクトモードへのモード切替時に、
必ず far jmp命令を行うことが仕様で決まっているのです。
CR0 の PE BITを1にしただけでは切り替わりません。その後に必ずfar jmp
命令を実行するまでがモード切替の手順の一部として決まっています。
>farジャンプは、パイプラインに残っている命令キューをフラッシュするためのものなので、セグメントリミットとはあまり関係ない
関係大有りです。リアルモードからプロテクトモードへのモード切替時に、
必ず far jmp命令を行うことが仕様で決まっているのです。
CR0 の PE BITを1にしただけでは切り替わりません。その後に必ずfar jmp
命令を実行するまでがモード切替の手順の一部として決まっています。
471デフォルトの名無しさん
2019/10/30(水) 09:09:35.16ID:C/RG5q83 >>469
CR0のPEビットを1にした状態でfar jmpするとプロテクトモードに切り替わります。
CR0のPEビットを1にした状態でfar jmpするとプロテクトモードに切り替わります。
472デフォルトの名無しさん
2019/10/30(水) 15:33:25.51ID:bv6PVv2A >>457
MonaOS 知ってる人減ったな
MonaOS 知ってる人減ったな
473デフォルトの名無しさん
2019/10/30(水) 23:02:51.33ID:6OkRkWLe >>466
残念ながらチクチク解析しないといけないです。なぜならもしコメントが残っていたら、「○○製品で使ったコード」とか
社内秘の内容が書いてあるかも知れず、そんなものが外に出たら大変だからです。
ソフトウェアのバージョンとか表に出ても構わない内容ならDBで定数文字列として書いておけばバイナリーにも
残るので逆アセンブルすれば見えます。
残念ながらチクチク解析しないといけないです。なぜならもしコメントが残っていたら、「○○製品で使ったコード」とか
社内秘の内容が書いてあるかも知れず、そんなものが外に出たら大変だからです。
ソフトウェアのバージョンとか表に出ても構わない内容ならDBで定数文字列として書いておけばバイナリーにも
残るので逆アセンブルすれば見えます。
474デフォルトの名無しさん
2019/10/30(水) 23:39:08.38ID:acFyRUep ダンプリストからでも処理を追えるから問題ない
475デフォルトの名無しさん
2019/10/31(木) 11:59:20.35ID:+ME5Ro2x 我々のコリブリ
476デフォルトの名無しさん
2019/11/01(金) 06:35:57.29ID:x4OgavLA Super ASCIIでDOSエクステンダーの連載があったな
その連載の最初の頃にプロテクトモードで64KBのリミッターを解除して
リアルモードに戻るサンプルプログラムが載ってた
DOSエクステンダーの話になってからは雑誌に載るソースコードは一部分のみで
全体のソースコード自体はASCIIがやってたアスキーネットで公開してたけど
その連載の最初の頃にプロテクトモードで64KBのリミッターを解除して
リアルモードに戻るサンプルプログラムが載ってた
DOSエクステンダーの話になってからは雑誌に載るソースコードは一部分のみで
全体のソースコード自体はASCIIがやってたアスキーネットで公開してたけど
477デフォルトの名無しさん
2019/11/01(金) 08:50:52.10ID:/dldU/F5 昔書いたコードを眺めてみたが
プロテクトモードに移るだけなら far jmp は必要なく、
shortジャンプでキューをクリアするだけで動いてたな
もちろん、16bitプロテクトモードに移るだけでcsのリミットも触っておらず
リアルモードと命令の意味が変わらない(命令長が変化しない等)からこそ出来る技
32bitモードに移行したらプリフィックスの意味も即値やアドレスの長さも全て変わるから
farジャンプは絶対必要だろう
386の時代の話だから、以後のでも通用するかはわからないが
プロテクトモードに移るだけなら far jmp は必要なく、
shortジャンプでキューをクリアするだけで動いてたな
もちろん、16bitプロテクトモードに移るだけでcsのリミットも触っておらず
リアルモードと命令の意味が変わらない(命令長が変化しない等)からこそ出来る技
32bitモードに移行したらプリフィックスの意味も即値やアドレスの長さも全て変わるから
farジャンプは絶対必要だろう
386の時代の話だから、以後のでも通用するかはわからないが
478デフォルトの名無しさん
2019/11/01(金) 08:51:34.31ID:/dldU/F5 こんな感じ
Enable4G proc
call Relocation
add ds:[D_GDTR].@BASE32, eax
pushr <ds, es>
pushf
cli
lgdt D_GDTR
mov eax, cr0
;and eax, not _PG
or al, _PE
mov cr0, eax
jmp short $+2 ;flush queue
movseg <ds, es>, GD_D4G, ax
mov eax, cr0
and al, not _PE
mov cr0, eax
jmp short $+2 ;flush queue
mov al, 2
out 0F6h, al ; A20マスク解除
sti
popf
popr
ret
endp
Enable4G proc
call Relocation
add ds:[D_GDTR].@BASE32, eax
pushr <ds, es>
pushf
cli
lgdt D_GDTR
mov eax, cr0
;and eax, not _PG
or al, _PE
mov cr0, eax
jmp short $+2 ;flush queue
movseg <ds, es>, GD_D4G, ax
mov eax, cr0
and al, not _PE
mov cr0, eax
jmp short $+2 ;flush queue
mov al, 2
out 0F6h, al ; A20マスク解除
sti
popf
popr
ret
endp
479デフォルトの名無しさん
2019/11/01(金) 08:53:59.78ID:/dldU/F5 で、仮想86モードに移行する時は、far jmpが必須
なぜなら、仮想86モードに移行するためには
仮想86モード用にセットアップされたTSSを使った特殊なタスクに移行する必要があり
そのためにはプロテクトモード内でのcsの書き換え、つまり、farjmpが必要となるから
これは呼び出し部分
GotoV86 proc
pushad
pushr <fs, gs>
pushf
call ModeSwitch
popf
mov al, 3
out 0F6h, al ; force A20 OFF
popr
popad
ret
endp
なぜなら、仮想86モードに移行するためには
仮想86モード用にセットアップされたTSSを使った特殊なタスクに移行する必要があり
そのためにはプロテクトモード内でのcsの書き換え、つまり、farjmpが必要となるから
これは呼び出し部分
GotoV86 proc
pushad
pushr <fs, gs>
pushf
call ModeSwitch
popf
mov al, 3
out 0F6h, al ; force A20 OFF
popr
popad
ret
endp
480デフォルトの名無しさん
2019/11/01(金) 08:54:59.94ID:/dldU/F5 ModeSwitch proc
; call Enable4G
call SetAddress
call SetupIDT
call SetupTSS
xor eax, eax
mov es, ax
call CleanEMB ; これ以降、es=0
call SetupPageTable
call MoveCode
call Setup8259A
prefixd32 ;32bit gdtr (not 24bit gdtr)
lgdt GDTR
prefixd32 ;32bit idtr (not 24bit idtr)
lidt IDTR
mov eax, cr0
or eax, _PG + _PE ; 直接ページングをON
mov cr0, eax
jmp short $+2 ; flush queue
mov ax, GD_D_TSS ; タスクレジスタにダミーの設定
ltr ax
call VGtest
FLUSH GD_V_TSS ; jmp far seg, $next
ret
endp
最後に far jmpしてる
; call Enable4G
call SetAddress
call SetupIDT
call SetupTSS
xor eax, eax
mov es, ax
call CleanEMB ; これ以降、es=0
call SetupPageTable
call MoveCode
call Setup8259A
prefixd32 ;32bit gdtr (not 24bit gdtr)
lgdt GDTR
prefixd32 ;32bit idtr (not 24bit idtr)
lidt IDTR
mov eax, cr0
or eax, _PG + _PE ; 直接ページングをON
mov cr0, eax
jmp short $+2 ; flush queue
mov ax, GD_D_TSS ; タスクレジスタにダミーの設定
ltr ax
call VGtest
FLUSH GD_V_TSS ; jmp far seg, $next
ret
endp
最後に far jmpしてる
481デフォルトの名無しさん
2019/11/01(金) 08:56:48.06ID:x4OgavLA Super ASCIIに載ってたサンプルコード
https://pastebin.com/0Tk0U9Y1
(TASMで動作確認済み)
PC9801用のテストプログラム(VRAMを80808080で埋めてるだけです)
.386p
assume cs:prog,ds:prog
prog segment use16
org 100h
mov ah,40h
int 18h
mov ah,42h
mov ch,0c0h
int 18h
mov eax,0
mov es,ax
mov edi,0a8000h
mov ecx, 32768*3/4
mov eax, 80808080h
cld
db 67h
; use ecx for loop counter
rep stosd
mov ax,4c00h
int 21h
prog ends
end
https://pastebin.com/0Tk0U9Y1
(TASMで動作確認済み)
PC9801用のテストプログラム(VRAMを80808080で埋めてるだけです)
.386p
assume cs:prog,ds:prog
prog segment use16
org 100h
mov ah,40h
int 18h
mov ah,42h
mov ch,0c0h
int 18h
mov eax,0
mov es,ax
mov edi,0a8000h
mov ecx, 32768*3/4
mov eax, 80808080h
cld
db 67h
; use ecx for loop counter
rep stosd
mov ax,4c00h
int 21h
prog ends
end
482デフォルトの名無しさん
2019/11/01(金) 08:58:53.01ID:x4OgavLA サンプルコード、テストプログラムともにCOM形式なので
LINKした後にexe2bin protect.exe protect.comとcom形式に変換する必要があります
LINKした後にexe2bin protect.exe protect.comとcom形式に変換する必要があります
483デフォルトの名無しさん
2019/11/01(金) 11:55:34.87ID:iX6unUP8 知らない人が多いようなので書いておくと、
実測してみると pusha より、ばらばらの push 命令を書いたほうが速度が速い。
一つの理由は、push espという無駄なpushが1つ減らせるから。
これはQEMUなどを使っているだけでは分からない事実。
なお、こっちは良く知られたことだけど、enter, leave 命令より、
push ebp, mov ebp,esp, sub esp, nn などと書くほうが速い。
もっと言えば、486だとなぜかinc, dec が2クロック掛かってしまうのに、
add esp,1 や sub esp,1 は1クロックで済むという事実を知る人は少ないらしい。
実測してみると pusha より、ばらばらの push 命令を書いたほうが速度が速い。
一つの理由は、push espという無駄なpushが1つ減らせるから。
これはQEMUなどを使っているだけでは分からない事実。
なお、こっちは良く知られたことだけど、enter, leave 命令より、
push ebp, mov ebp,esp, sub esp, nn などと書くほうが速い。
もっと言えば、486だとなぜかinc, dec が2クロック掛かってしまうのに、
add esp,1 や sub esp,1 は1クロックで済むという事実を知る人は少ないらしい。
484デフォルトの名無しさん
2019/11/01(金) 11:58:53.09ID:iX6unUP8 >>483
補足。QEMU だと、pusha が1命令分の時間で済むのに対し、バラバラの
push命令に直してしまうと、その個数倍の時間が掛かるので、8倍程度後者
の方が遅い。実機だと、後者の方が16%程度速い。実機とQEMUでは全然
速度バランスが違うので、QEMUでの速度測定は全く参考にならないので注意。
補足。QEMU だと、pusha が1命令分の時間で済むのに対し、バラバラの
push命令に直してしまうと、その個数倍の時間が掛かるので、8倍程度後者
の方が遅い。実機だと、後者の方が16%程度速い。実機とQEMUでは全然
速度バランスが違うので、QEMUでの速度測定は全く参考にならないので注意。
485デフォルトの名無しさん
2019/11/01(金) 12:10:32.63ID:iX6unUP8 >>477
正確には short jmp だったか、far jump だったかは資料を見てみないと
思い出せないけど、少なくとも Wikibooksには、
6. Set the PE bit (and the PG bit if paging is going to be enabled) of the
MSW or CR0 register
7. Execute a far jump (in case of switching to long mode, even if the destination
code segment is a 64-bit code segment, the offset must not exceed 32-bit
since the far jump instruction is executed in compatibility mode)
また、https://stackoverflow.com/questions/26679682/how-does-setting-the-pe-flag-in-cr0-enable-protected-mode
にも、
1. Set up a global descriptor table (gdt) and load it using the lgdt instruction
2. Set the PE flag/bit in the control register CR0 to enabled (ie. to the value 1)
3. Execute a long jump with ljmp
Technically the CPU internally stores the selector information of all selectors used.
Whenever a selector register changes then the limit, base and so on are loaded.
This means that loading the CS register is required for updating the base, limit
and so of the CS register. This means: A far jump must be done (because this
will load the CS register). Maybe a RETF would also work...
I'm not sure if loading the other segment registers (for example DS) would
already work before the far jump so if you load the DS register before the
far jump the base address and limit will be taken from the GDT. Would be
nice to try this out...
と書かれている。
正確には short jmp だったか、far jump だったかは資料を見てみないと
思い出せないけど、少なくとも Wikibooksには、
6. Set the PE bit (and the PG bit if paging is going to be enabled) of the
MSW or CR0 register
7. Execute a far jump (in case of switching to long mode, even if the destination
code segment is a 64-bit code segment, the offset must not exceed 32-bit
since the far jump instruction is executed in compatibility mode)
また、https://stackoverflow.com/questions/26679682/how-does-setting-the-pe-flag-in-cr0-enable-protected-mode
にも、
1. Set up a global descriptor table (gdt) and load it using the lgdt instruction
2. Set the PE flag/bit in the control register CR0 to enabled (ie. to the value 1)
3. Execute a long jump with ljmp
Technically the CPU internally stores the selector information of all selectors used.
Whenever a selector register changes then the limit, base and so on are loaded.
This means that loading the CS register is required for updating the base, limit
and so of the CS register. This means: A far jump must be done (because this
will load the CS register). Maybe a RETF would also work...
I'm not sure if loading the other segment registers (for example DS) would
already work before the far jump so if you load the DS register before the
far jump the base address and limit will be taken from the GDT. Would be
nice to try this out...
と書かれている。
486デフォルトの名無しさん
2019/11/01(金) 12:19:54.06ID:iX6unUP8 >>485
だんだん思い出してきたので書いておくと、GDTRにGDTのアドレスをセットした
だけでは、CPU内部のセグメントレジスタの情報が更新されない。
例えば、dsには、リミット、ベースアドレスなどの情報がCPU内部に入っているが、
GDTRを更新した段階では、CPU内部のそれらの情報は更新されない。
更新されるのは、mov ds,ax や、pop ds, lds などを実行した場合のみ。
つまり、mov ds,ax などを実行して始めて、CPU内部のdsレジスタに関する隠れ
情報格納場所の情報までが更新され、dsにプロテクトモードらしいセグメントが
対応するようになる。
一方、csレジスタについては、mov cs,ax などの命令が無いので、その代わりになる
のが、far jmp ということになる。far ret や iret などでもいけるかもしれないが、
仕様上は far jmp ということになっているのだと思う。だから、プロテクトモードに
初めて突入したい場合に、far jmp 以外の命令でcs を更新した場合にどうなるかは
保証されていないかもしれない。
だんだん思い出してきたので書いておくと、GDTRにGDTのアドレスをセットした
だけでは、CPU内部のセグメントレジスタの情報が更新されない。
例えば、dsには、リミット、ベースアドレスなどの情報がCPU内部に入っているが、
GDTRを更新した段階では、CPU内部のそれらの情報は更新されない。
更新されるのは、mov ds,ax や、pop ds, lds などを実行した場合のみ。
つまり、mov ds,ax などを実行して始めて、CPU内部のdsレジスタに関する隠れ
情報格納場所の情報までが更新され、dsにプロテクトモードらしいセグメントが
対応するようになる。
一方、csレジスタについては、mov cs,ax などの命令が無いので、その代わりになる
のが、far jmp ということになる。far ret や iret などでもいけるかもしれないが、
仕様上は far jmp ということになっているのだと思う。だから、プロテクトモードに
初めて突入したい場合に、far jmp 以外の命令でcs を更新した場合にどうなるかは
保証されていないかもしれない。
487デフォルトの名無しさん
2019/11/02(土) 18:02:51.42ID:cEPd2nC/ 低レベルな相談です
ADDL・ADDA・SUBL・SUBA・AND・OR・XOR・CPL・CPA命令において
オペランドの第2引数に、=を付けるのをつい忘れてしまうんですが、
何か対処法はありますか?
ADDL・ADDA・SUBL・SUBA・AND・OR・XOR・CPL・CPA命令において
オペランドの第2引数に、=を付けるのをつい忘れてしまうんですが、
何か対処法はありますか?
488デフォルトの名無しさん
2019/11/02(土) 22:19:49.20ID:dJ3V2vrm >>487
CASL II は始めて見たんだけど、
http://masudahp.web.fc2.com/casl2/casl2110.html
http://masudahp.web.fc2.com/casl2/casl2120.html
ADDA GR0, =#0045
のように書くと、自動的にラベルを生成して、
ADDA GR0, DATA1
・・・
DATA1 DC #0045
と書いたの等価になるらしいから、忘れるとか言う問題ではなく、
CASL II言語の基礎なので自然に覚えるしかないですね。
アセンブリプログラミングには、このくらいの記憶力は必要です。
ただ、丸覚えするのではなく、ちゃんと理解すれば自然に覚えられると思います。
CASL II は始めて見たんだけど、
http://masudahp.web.fc2.com/casl2/casl2110.html
http://masudahp.web.fc2.com/casl2/casl2120.html
ADDA GR0, =#0045
のように書くと、自動的にラベルを生成して、
ADDA GR0, DATA1
・・・
DATA1 DC #0045
と書いたの等価になるらしいから、忘れるとか言う問題ではなく、
CASL II言語の基礎なので自然に覚えるしかないですね。
アセンブリプログラミングには、このくらいの記憶力は必要です。
ただ、丸覚えするのではなく、ちゃんと理解すれば自然に覚えられると思います。
489デフォルトの名無しさん
2019/11/02(土) 22:41:38.43ID:dJ3V2vrm >>488
実際のCASL IIがそう書けるかどうかはともかくとして、
数学記号と同様の感覚で記号の対応関係や「類推(推論)」で考えれば、
ADDA GR0,#0045
と書くと、アドレス #0045 番地のメモリーに入っている内容を読み出した値を
GR0に足す、という意味になります。# は以後の数値が16進数である事を表す
記号です。初めに言ったようにこの書き方がCASL II 言語で実際に出来るか
どうかは分かりませんが、意味で考えるとそういう意味になるでしょう。一方、
ADDA GR0,=#0045
は、>>488 に書いたように、0045 という16進数の値を入れた領域を
自動的に確保して、そのアドレスを xxx とすると、自動的にその場所を
ADDA GR0,xxx
という命令に置き換えるという意味です。
かなり違う意味です。ですから、覚える覚えないの話では無い事が分かります。
実際のCASL IIがそう書けるかどうかはともかくとして、
数学記号と同様の感覚で記号の対応関係や「類推(推論)」で考えれば、
ADDA GR0,#0045
と書くと、アドレス #0045 番地のメモリーに入っている内容を読み出した値を
GR0に足す、という意味になります。# は以後の数値が16進数である事を表す
記号です。初めに言ったようにこの書き方がCASL II 言語で実際に出来るか
どうかは分かりませんが、意味で考えるとそういう意味になるでしょう。一方、
ADDA GR0,=#0045
は、>>488 に書いたように、0045 という16進数の値を入れた領域を
自動的に確保して、そのアドレスを xxx とすると、自動的にその場所を
ADDA GR0,xxx
という命令に置き換えるという意味です。
かなり違う意味です。ですから、覚える覚えないの話では無い事が分かります。
490デフォルトの名無しさん
2019/11/02(土) 22:47:11.43ID:dJ3V2vrm >>489
x86アセンブラを知っている人ならば、
ADDA GR0,GR1 ---> mov GR0,dword ptr [GR1]
ADDA GR0,#0045 ---> mov GR0,dword ptr [0045h]
ADDA GR0,=#0045 ---> mov GR0,0045h
また、C言語を知っている人ならば、
ADDA GR0,GR1 ---> GR0 += *(DWORD *)GR1;
ADDA GR0,#0045 ---> GR0 += *(DWORD *)0x0045;
ADDA GR0,=#0045 ---> GR0 += 0x0045;
となります。
対応関係は、第二オペランドに X を書くと、[X] や、*X の意味になり、
=X と書くと、X の意味になります。
x86アセンブラを知っている人ならば、
ADDA GR0,GR1 ---> mov GR0,dword ptr [GR1]
ADDA GR0,#0045 ---> mov GR0,dword ptr [0045h]
ADDA GR0,=#0045 ---> mov GR0,0045h
また、C言語を知っている人ならば、
ADDA GR0,GR1 ---> GR0 += *(DWORD *)GR1;
ADDA GR0,#0045 ---> GR0 += *(DWORD *)0x0045;
ADDA GR0,=#0045 ---> GR0 += 0x0045;
となります。
対応関係は、第二オペランドに X を書くと、[X] や、*X の意味になり、
=X と書くと、X の意味になります。
491デフォルトの名無しさん
2019/11/02(土) 22:48:31.37ID:dJ3V2vrm >>490
すみません、movとaddを書き間違えました。正しくはこうです。:
x86アセンブラを知っている人ならば、
ADDA GR0,GR1 ---> add GR0,dword ptr [GR1]
ADDA GR0,#0045 ---> add GR0,dword ptr [0045h]
ADDA GR0,=#0045 ---> add GR0,0045h
すみません、movとaddを書き間違えました。正しくはこうです。:
x86アセンブラを知っている人ならば、
ADDA GR0,GR1 ---> add GR0,dword ptr [GR1]
ADDA GR0,#0045 ---> add GR0,dword ptr [0045h]
ADDA GR0,=#0045 ---> add GR0,0045h
493デフォルトの名無しさん
2019/11/12(火) 18:31:03.25ID:m5a+lCw/ マイコン用のアセンブラコードジェネレータを作りたいんだけどどんな感じにするのが良いんだろうか
if文で条件分岐させていくとコード生成部が条件分岐だらけになって訳が判らなくなる
組み込み用なのでパイプラインのストールを引き起こすようなコードはなるべく生成したくない
if文で条件分岐させていくとコード生成部が条件分岐だらけになって訳が判らなくなる
組み込み用なのでパイプラインのストールを引き起こすようなコードはなるべく生成したくない
494デフォルトの名無しさん
2019/11/12(火) 18:53:07.41ID:I0vQskxn bison+flex+LLVM
495デフォルトの名無しさん
2019/11/12(火) 23:09:55.20ID:We/BiDY5 >>493
テーブル参照して引っ張ってくるのが一番楽かと
テーブル参照して引っ張ってくるのが一番楽かと
496デフォルトの名無しさん
2019/11/13(水) 01:29:11.05ID:6OGWlygT やる気だけでは進まない
497493
2019/11/13(水) 08:08:30.10ID:HNnV6bHC ありがとう
>>494
判りにくくてスマン。ガチの処理系を作りたいわけではないんだ
チップメーカーが出しているGUIでパラメータをポチポチ設定してGeneratボタンをクリックすると
設定に従ったライブラリコードを自動生成してくれるみたいな奴を作りたい
というかLLVMとかは自分の手におえそうにない
>>495
ハッシュテーブルみたいな感じ?パターンは結構ある
今考えているパラメータだけでも
書き込み先アドレスが〜30種程度と〜10種類程度×2
処理の選択にbool値が5個くらい、サイクル数指定が3種
サイクル数を指定できる区間は重なっているし結構ややこしい
ちょっと前から作り始めているけどすでにぐちゃぐちゃ・・・
>>494
判りにくくてスマン。ガチの処理系を作りたいわけではないんだ
チップメーカーが出しているGUIでパラメータをポチポチ設定してGeneratボタンをクリックすると
設定に従ったライブラリコードを自動生成してくれるみたいな奴を作りたい
というかLLVMとかは自分の手におえそうにない
>>495
ハッシュテーブルみたいな感じ?パターンは結構ある
今考えているパラメータだけでも
書き込み先アドレスが〜30種程度と〜10種類程度×2
処理の選択にbool値が5個くらい、サイクル数指定が3種
サイクル数を指定できる区間は重なっているし結構ややこしい
ちょっと前から作り始めているけどすでにぐちゃぐちゃ・・・
498デフォルトの名無しさん
2019/11/21(木) 00:03:41.36ID:Sj//p0Te 初歩的な質問です
8086とZ80だったらどっちを勉強した方が良いですか?
8086とZ80だったらどっちを勉強した方が良いですか?
499デフォルトの名無しさん
2019/11/21(木) 01:21:24.28ID:FiaSI4dm 8086
500デフォルトの名無しさん
2019/11/21(木) 01:21:54.93ID:FiaSI4dm x64じゃいかんの?
501デフォルトの名無しさん
2019/11/21(木) 02:11:07.86ID:dnQ3Bqh9 z80だろ
502デフォルトの名無しさん
2019/11/21(木) 02:13:40.22ID:dnQ3Bqh9 >>498
やっぱ両方いらん
やっぱ両方いらん
503デフォルトの名無しさん
2019/11/21(木) 05:15:38.34ID:1McLuuYz すでに何かのアセンブラ理解してるなら両方勉強しても数日で理解できるだろう。
はじめてアセンブラ勉強するならそりゃシンプルな8bitCPUで圧倒的に情報が多いZ80だろうな。
はじめてアセンブラ勉強するならそりゃシンプルな8bitCPUで圧倒的に情報が多いZ80だろうな。
504498
2019/11/22(金) 00:24:30.25ID:I5J2JfnT 返信が遅くなってすいません
答えて頂いた方、ありがとうございました
答えて頂いた方、ありがとうございました
505デフォルトの名無しさん
2019/11/22(金) 13:34:09.59ID:zKQgPoBc マジレスするとアセンブラを使う目的次第
PICやRL78みたいな小規模でCPUや電子回路を学ぶ
x64で高速化やSIMDを試す
ラズベリーパイやスマホのARMで遊んでみる
DSPで信号処理やフィードバック制御を学ぶ
など
PICやRL78みたいな小規模でCPUや電子回路を学ぶ
x64で高速化やSIMDを試す
ラズベリーパイやスマホのARMで遊んでみる
DSPで信号処理やフィードバック制御を学ぶ
など
506デフォルトの名無しさん
2019/11/22(金) 15:29:17.71ID:gUUFthXr >>498
6809
6809
507デフォルトの名無しさん
2019/11/22(金) 16:26:18.45ID:2jFqraTL508デフォルトの名無しさん
2019/11/22(金) 16:34:56.93ID:2jFqraTL >>507
ちなみに、CPUとしては両者は親戚みたいなもので、Z80を学んだ後から、
8086へ進んでも文化に共通点が多いので理解し易い。
たとえば、条件分岐は、cmpなどの比較命令を実行して
zero flag や carry flag などに影響を与えた後に、Jcc 命令を使う点や、
cmp以外にsubやaddでも全く同様に zero flag, carry flag などに影響を
与えると言う点が両者で共通している。
他のCPUでは全く違うやり方をとるものも多い。
ところが、Z80は8BIT CPU としてはとても上手くできていた方だが、
8086は、16BIT CPU としては残念な方であった。一つの理由は、
当時は低価格で理想的な16BIT CPUを作るためには、ICにおけるトランジスタの
集積度が不足していたが、8BIT CPUを作るには十分であったためらしい。
なので、8BIT CPUは使い易いものが作れたが、16BIT CPU は使いにくいもの
しか作れなかった、と考えることが出来る。
ちなみに、CPUとしては両者は親戚みたいなもので、Z80を学んだ後から、
8086へ進んでも文化に共通点が多いので理解し易い。
たとえば、条件分岐は、cmpなどの比較命令を実行して
zero flag や carry flag などに影響を与えた後に、Jcc 命令を使う点や、
cmp以外にsubやaddでも全く同様に zero flag, carry flag などに影響を
与えると言う点が両者で共通している。
他のCPUでは全く違うやり方をとるものも多い。
ところが、Z80は8BIT CPU としてはとても上手くできていた方だが、
8086は、16BIT CPU としては残念な方であった。一つの理由は、
当時は低価格で理想的な16BIT CPUを作るためには、ICにおけるトランジスタの
集積度が不足していたが、8BIT CPUを作るには十分であったためらしい。
なので、8BIT CPUは使い易いものが作れたが、16BIT CPU は使いにくいもの
しか作れなかった、と考えることが出来る。
509デフォルトの名無しさん
2019/11/22(金) 16:45:49.82ID:gUUFthXr 80186 で恥の上塗りですね判ります
510デフォルトの名無しさん
2019/11/22(金) 16:56:01.19ID:2jFqraTL >>508
他にも、
1. 両者とも、アラインの揃ってないアドレスからでも16BIT以上のデータを
読み出せると言う特徴がある。これが出来ないCPUも多く、Apple系は昔そういう
CPUを使っていたと聞いている。今でもC言語の構造体などで align が細々と
決まっているのは、後者の文化圏の人達が主導しているのかも知れない。
2. carry flag(8086 では「borrow flag」という名前になっている)を使うと、
多倍長の加減算が容易に出来るのも両社に共通している。この特徴は、
他のCPUには無いことが多いらしい。だから、LLVMなどには adc や sbc(sbb)
相当の命令が無いし、carry flag を捕捉する命令も定義されていない。
3. LLVM では、単純な引き算の延長線上にある cmp 命令でフラグを作った後、
条件の種類によっていろいろな種類のJcc で条件分岐するという流儀をとっておらず、
条件の種類によって比較命令自体を変えてしまって、結果は常に 1BIT の
BOOL値とし。逆に Jcc 命令は原則一種類となっている。これは、LLVMが
Z80や8086とは異なる文化圏の人が作ったものであるのではないかと推定される。
4.アカデミカルな世界では、CPUとして、業界事実標準の Z80 や 8086 系統ではなく、
どうも違う文化のものを想定していることが多い気がする。
色々な言葉が、Z80 や 8086 ではかなり多く共通しているが、LLVMとは全く
違う。
他にも、
1. 両者とも、アラインの揃ってないアドレスからでも16BIT以上のデータを
読み出せると言う特徴がある。これが出来ないCPUも多く、Apple系は昔そういう
CPUを使っていたと聞いている。今でもC言語の構造体などで align が細々と
決まっているのは、後者の文化圏の人達が主導しているのかも知れない。
2. carry flag(8086 では「borrow flag」という名前になっている)を使うと、
多倍長の加減算が容易に出来るのも両社に共通している。この特徴は、
他のCPUには無いことが多いらしい。だから、LLVMなどには adc や sbc(sbb)
相当の命令が無いし、carry flag を捕捉する命令も定義されていない。
3. LLVM では、単純な引き算の延長線上にある cmp 命令でフラグを作った後、
条件の種類によっていろいろな種類のJcc で条件分岐するという流儀をとっておらず、
条件の種類によって比較命令自体を変えてしまって、結果は常に 1BIT の
BOOL値とし。逆に Jcc 命令は原則一種類となっている。これは、LLVMが
Z80や8086とは異なる文化圏の人が作ったものであるのではないかと推定される。
4.アカデミカルな世界では、CPUとして、業界事実標準の Z80 や 8086 系統ではなく、
どうも違う文化のものを想定していることが多い気がする。
色々な言葉が、Z80 や 8086 ではかなり多く共通しているが、LLVMとは全く
違う。
511デフォルトの名無しさん
2019/11/22(金) 17:05:38.22ID:zKQgPoBc まあ普通にx64かARMかMIPS
ARMやMIPSはもともとRISCなので非常にきれいでシンプル
x64はAVXなどのリッチな命令を楽しめるし
環境もPCにVisual Studioを入れるだけ
ARMやMIPSはもともとRISCなので非常にきれいでシンプル
x64はAVXなどのリッチな命令を楽しめるし
環境もPCにVisual Studioを入れるだけ
512デフォルトの名無しさん
2019/11/22(金) 17:09:00.41ID:zKQgPoBc 80186(改)は実はわりと最近まで製品で使ってましたよ
大きなLSIの中に、制御用にコアだけ入ってるやつ
セグメントレジスタが4シフトではなく8シフト
大きなLSIの中に、制御用にコアだけ入ってるやつ
セグメントレジスタが4シフトではなく8シフト
513デフォルトの名無しさん
2019/11/22(金) 17:10:09.89ID:omZwaM5I >>510
シッタカで出鱈目書くなよ糞が
シッタカで出鱈目書くなよ糞が
514デフォルトの名無しさん
2019/11/22(金) 17:11:44.26ID:zKQgPoBc すいません
515デフォルトの名無しさん
2019/11/22(金) 17:11:56.78ID:zKQgPoBc おれじゃなかった
516デフォルトの名無しさん
2019/11/22(金) 17:54:18.76ID:UNbCtceI517デフォルトの名無しさん
2019/11/22(金) 18:28:01.42ID:hDmJhEnO >>510じゃないけど
1.性能上(もしくはアトミック性)の理由でアラインメントを揃える
2.8086でもキャリーフラグという名前
もちろんボローの意味でも使う
フラグはOut Of Orderの妨げになりやすく
シンプルな設計を目指したRISC系では使わないし
当然SIMDでも使わない
ただし、命令を組み合わせて同じことが出来る
多倍長の加減算は(乗算他に比べて)速いので
それが性能に影響することは少ないし
64bit CPUではそもそも64bitを越えた演算をすることも非常に少ない
1.性能上(もしくはアトミック性)の理由でアラインメントを揃える
2.8086でもキャリーフラグという名前
もちろんボローの意味でも使う
フラグはOut Of Orderの妨げになりやすく
シンプルな設計を目指したRISC系では使わないし
当然SIMDでも使わない
ただし、命令を組み合わせて同じことが出来る
多倍長の加減算は(乗算他に比べて)速いので
それが性能に影響することは少ないし
64bit CPUではそもそも64bitを越えた演算をすることも非常に少ない
518デフォルトの名無しさん
2019/11/22(金) 18:29:07.76ID:hDmJhEnO519デフォルトの名無しさん
2019/11/22(金) 18:33:09.28ID:hDmJhEnO 4.z80はまったく業界標準ではないですね
数量から言えばARMとx86系が圧倒的
MIPSは教育現場では使われるけど
数量はARMやx86系に比べたら少ない
x86も16bit命令で組む事はほぼない
32bitか64bitがほとんど
数量から言えばARMとx86系が圧倒的
MIPSは教育現場では使われるけど
数量はARMやx86系に比べたら少ない
x86も16bit命令で組む事はほぼない
32bitか64bitがほとんど
520デフォルトの名無しさん
2019/11/22(金) 18:35:52.35ID:hDmJhEnO あとは教育だとRISC-Vとか
521デフォルトの名無しさん
2019/11/22(金) 18:35:58.82ID:z6OUhbA9 ARM系の条件分岐ってフラグベースじゃね?
522デフォルトの名無しさん
2019/11/22(金) 18:43:24.01ID:LRWcxGhp いまどき初心者がZ80に興味持つはずないだろ
こいつが御高説を垂れたいがために質問を自演してるんだろ
情けない奴
こいつが御高説を垂れたいがために質問を自演してるんだろ
情けない奴
523デフォルトの名無しさん
2019/11/22(金) 19:07:15.94ID:sA8M4Dff Z80そのものが使われる機会は減っていてもZ80の流れを汲むアーキテクチャはまだまだある
IA32/AMD64はもちろん、ちょっと上であがっているRL78もだ
IA32/AMD64はもちろん、ちょっと上であがっているRL78もだ
524デフォルトの名無しさん
2019/11/22(金) 19:10:46.49ID:hDmJhEnO525デフォルトの名無しさん
2019/11/22(金) 19:26:38.06ID:sA8M4Dff 組み込み系でも8bitだと桁上がり演算でキャリーをよく使うけど32bitだと出番は激減する
32bitあれば12bitADCの変換値を10回足し込むくらいじゃ余裕
一部のアーキテクチャは特殊演算用に64bitを超えるレジスタを持っていたりするし
なおさら桁あふれしにくい
32bitあれば12bitADCの変換値を10回足し込むくらいじゃ余裕
一部のアーキテクチャは特殊演算用に64bitを超えるレジスタを持っていたりするし
なおさら桁あふれしにくい
526デフォルトの名無しさん
2019/11/22(金) 20:20:02.18ID:LRWcxGhp >>523
ID変えて否定に回ったのが自演の証拠w
ID変えて否定に回ったのが自演の証拠w
527デフォルトの名無しさん
2019/11/22(金) 21:52:14.02ID:DXtwsE0I Intel系のCPUは元々4bitの4004から来ている。4004は主に電卓で使われた。4bitレジスタで演算するとき
桁あふれが頻繁に起こるのがわかっていたのでキャリーフラグがあると便利だろうということで入れたんだと思う。
それが8bitの8008以降も継承されて現在に至る。だから64bitでキャリーフラグが使われないのも当然。
桁あふれが頻繁に起こるのがわかっていたのでキャリーフラグがあると便利だろうということで入れたんだと思う。
それが8bitの8008以降も継承されて現在に至る。だから64bitでキャリーフラグが使われないのも当然。
528デフォルトの名無しさん
2019/11/22(金) 22:00:58.35ID:uBbdr9rC 最後の「だから」がなぜ「だから」なのかわからない
529デフォルトの名無しさん
2019/11/22(金) 22:22:56.50ID:2jFqraTL >>517
>ただし、命令を組み合わせて同じことが出来る
一年ほど前に調べていたら、x+y に対するキャリーフラグをC言語を使って
作り出すようなことを書いているコードを見つけた。
普通に考えればx,yの最上位ビットに着目すればいいんだけど、
最初に思いつくコードよりかなり短いコードだった。
x,yが8BITの場合、x+yに対するキャリーフラグをcfとすると、
意味的には、
cf = 0;
if ( (x & 0x80) != 0 && (y & 0x80) != 0 ) {
cf = 1;
}
でいいはずだけど、
cf = (x & y) >> 7;
かな。でも、もっとエレガントなコードだったような気がする。
何か知っていれば教えて欲しい。
>ただし、命令を組み合わせて同じことが出来る
一年ほど前に調べていたら、x+y に対するキャリーフラグをC言語を使って
作り出すようなことを書いているコードを見つけた。
普通に考えればx,yの最上位ビットに着目すればいいんだけど、
最初に思いつくコードよりかなり短いコードだった。
x,yが8BITの場合、x+yに対するキャリーフラグをcfとすると、
意味的には、
cf = 0;
if ( (x & 0x80) != 0 && (y & 0x80) != 0 ) {
cf = 1;
}
でいいはずだけど、
cf = (x & y) >> 7;
かな。でも、もっとエレガントなコードだったような気がする。
何か知っていれば教えて欲しい。
530デフォルトの名無しさん
2019/11/22(金) 22:28:55.69ID:2jFqraTL さらに、x, y が符号なし8BIT整数の場合の x - y に対する carry flag については、
cf = 0;
if ( x < y ) cf = 1;
で一応求まるんだと思う。
また、sf(sign flag) に関しては、
sf = 演算結果 >> 7;
でいいと思われる。
cf = 0;
if ( x < y ) cf = 1;
で一応求まるんだと思う。
また、sf(sign flag) に関しては、
sf = 演算結果 >> 7;
でいいと思われる。
531デフォルトの名無しさん
2019/11/22(金) 22:33:04.48ID:2jFqraTL532デフォルトの名無しさん
2019/11/22(金) 22:40:25.25ID:2jFqraTL533デフォルトの名無しさん
2019/11/22(金) 22:46:49.23ID:2jFqraTL >>532
すまん。後半部は間違いらしい。
すまん。後半部は間違いらしい。
534デフォルトの名無しさん
2019/11/22(金) 23:19:09.49ID:2jFqraTL535デフォルトの名無しさん
2019/11/23(土) 00:09:22.51ID:zs0Ad1fs >>528
64bitレジスタでは4bitレジスタに比べて桁あふれが起きにくいから使用頻度が少なくなる。
64bitレジスタでは4bitレジスタに比べて桁あふれが起きにくいから使用頻度が少なくなる。
536デフォルトの名無しさん
2019/11/23(土) 02:42:52.78ID:eMnkZzKn 足し算
z0 = x0+y0;
z1 = x1+y1+(z0<x0);
引き算
z0 = x0-y0;
z1 = x1-y1-(z0>x0);
z0 = x0+y0;
z1 = x1+y1+(z0<x0);
引き算
z0 = x0-y0;
z1 = x1-y1-(z0>x0);
537デフォルトの名無しさん
2019/11/23(土) 03:01:11.70ID:eMnkZzKn carry = 0;
for (i=0 ; i < n ; i++){
. . if (carry){
. . . . z[i] = x[i] + y[i];
. . . . carry = z[i] < x[i];
. . }
. . else {
. . . . z[i] = x[i] + y[i] + 1;
. . . . carry = z[i] <= x[i];
. . }
}
for (i=0 ; i < n ; i++){
. . if (carry){
. . . . z[i] = x[i] + y[i];
. . . . carry = z[i] < x[i];
. . }
. . else {
. . . . z[i] = x[i] + y[i] + 1;
. . . . carry = z[i] <= x[i];
. . }
}
538デフォルトの名無しさん
2019/11/23(土) 03:03:32.41ID:eMnkZzKn borrow = 0;
for (i=0 ; i < n ; i++){
. . if (carry){
. . . . z[i] = x[i] - y[i];
. . . . borrow = z[i] > x[i];
. . }
. . else {
. . . . z[i] = x[i] - y[i] - 1;
. . . . borrow = z[i] >= x[i];
. . }
}
for (i=0 ; i < n ; i++){
. . if (carry){
. . . . z[i] = x[i] - y[i];
. . . . borrow = z[i] > x[i];
. . }
. . else {
. . . . z[i] = x[i] - y[i] - 1;
. . . . borrow = z[i] >= x[i];
. . }
}
539529
2019/11/23(土) 11:50:40.96ID:U8iKLMmJ 自己訂正です。
実は、色々と間違いがあり、次のようになっています:
>>529 : 間違い。
530 : 正しい。
531 : 正しい。
>>532 の前半 : 正しい。
>>532 の後半 : 間違い。
改めて、>>529 の根本的な間違いとして、carry flag は、演算前の最上位ビットだけでは決まる、
というのが大間違いでした。下位ビットからの桁上がりがあるためです。
まとめると、x, y が符号なし整数の場合、
1. a = x - y に対する carry flag :
cf = (x < y);
または。
cf = (a > x);
2. a = x + y に対する carry flag :
cf = (x < (-y));
または。
cf = (a < x);
です。上記の「または」以後のやり方は、>>536 537 538 で思い出させていただきました。
一年ほど前に見たやり方がそれだったと思います。とてもエレガントですね。
実は、色々と間違いがあり、次のようになっています:
>>529 : 間違い。
530 : 正しい。
531 : 正しい。
>>532 の前半 : 正しい。
>>532 の後半 : 間違い。
改めて、>>529 の根本的な間違いとして、carry flag は、演算前の最上位ビットだけでは決まる、
というのが大間違いでした。下位ビットからの桁上がりがあるためです。
まとめると、x, y が符号なし整数の場合、
1. a = x - y に対する carry flag :
cf = (x < y);
または。
cf = (a > x);
2. a = x + y に対する carry flag :
cf = (x < (-y));
または。
cf = (a < x);
です。上記の「または」以後のやり方は、>>536 537 538 で思い出させていただきました。
一年ほど前に見たやり方がそれだったと思います。とてもエレガントですね。
540デフォルトの名無しさん
2019/11/25(月) 14:32:25.64ID:1+9AnSdf MIPS64やRISC-VのRV64Iで128bit加算減算のアセンブラ出力してみると
おなじようなことやってるね
mips64 128bit加算 $4:$2 ← $5:$4 + $7:$6
daddu $2,$4,$6
sltu $8,$2,$4
dext $8,$8,0,32
daddu $3,$5,$7
daddu $4,$8,$3
mips64 128bit減算 $4:$2 ← $5:$4 - $7:$6
dsubu $2,$4,$6
sltu $8,$4,$2
dext $8,$8,0,32
dsubu $3,$5,$7
dsubu $4,$3,$8
risc-v RV64I 128bit加算 a6:a7 ← a1:a0 + a3:a2
add a7,a0,a2
sltu a6,a7,a0
add t1,a1,a3
add a6,a6,t1
risc-v RV64I 128bit減算 a1:a2 ← a1:a0 - a3:a2
sub a2,a0,a2
sgtu a0,a2,a0
sub a1,a1,a3
sub a1,a1,a0
おなじようなことやってるね
mips64 128bit加算 $4:$2 ← $5:$4 + $7:$6
daddu $2,$4,$6
sltu $8,$2,$4
dext $8,$8,0,32
daddu $3,$5,$7
daddu $4,$8,$3
mips64 128bit減算 $4:$2 ← $5:$4 - $7:$6
dsubu $2,$4,$6
sltu $8,$4,$2
dext $8,$8,0,32
dsubu $3,$5,$7
dsubu $4,$3,$8
risc-v RV64I 128bit加算 a6:a7 ← a1:a0 + a3:a2
add a7,a0,a2
sltu a6,a7,a0
add t1,a1,a3
add a6,a6,t1
risc-v RV64I 128bit減算 a1:a2 ← a1:a0 - a3:a2
sub a2,a0,a2
sgtu a0,a2,a0
sub a1,a1,a3
sub a1,a1,a0
541デフォルトの名無しさん
2019/11/25(月) 18:08:28.75ID:FcoOoav6 だろうね
542デフォルトの名無しさん
2019/11/28(木) 08:12:36.09ID:xy0IaHJE543デフォルトの名無しさん
2019/11/28(木) 08:14:06.75ID:xy0IaHJE MIPS以降の多くのRISCベースのCPUはすべてキャリーフラグがある。
とても効率的で不可欠だからだ。
とても効率的で不可欠だからだ。
544デフォルトの名無しさん
2019/11/28(木) 19:38:36.20ID:jGkkl6Qu545デフォルトの名無しさん
2019/11/28(木) 19:56:47.34ID:PoPpbfsh フラグはアウトオブオーダーの妨げになるし
並列化も出来ないから
高速化に対してはイマイチ
並列化も出来ないから
高速化に対してはイマイチ
546デフォルトの名無しさん
2019/11/28(木) 20:01:39.23ID:aqT8+si8547デフォルトの名無しさん
2019/11/28(木) 20:15:33.90ID:jGkkl6Qu >>546
それって一々フラグを意識しないだろ。
それって一々フラグを意識しないだろ。
548デフォルトの名無しさん
2019/11/28(木) 20:34:30.59ID:d3vL2dOV 話にならねえな
549デフォルトの名無しさん
2019/11/28(木) 21:08:35.99ID:jGkkl6Qu じゃあ止めよう
550デフォルトの名無しさん
2019/11/28(木) 21:56:14.84ID:aqT8+si8 jbという条件ジャンプ命令は使っているけど
jcという条件ジャンプ命令は使っていないので、キャリーフラグを使うことはない
アホくさ
jcという条件ジャンプ命令は使っていないので、キャリーフラグを使うことはない
アホくさ
551デフォルトの名無しさん
2019/11/28(木) 23:10:51.33ID:xy0IaHJE552デフォルトの名無しさん
2019/11/29(金) 01:09:48.76ID:IDh/GqUP 条件分岐でキャリーフラグの使い方が分からない、使ったことがない、使われることを知らなかった、という人はなんだろう。
6502、Z80、6809、AVR、8086、68K、ARMとメジャーなCPUどれから始めてもマニュアル、入門書には書いてると思う。
6502、Z80、6809、AVR、8086、68K、ARMとメジャーなCPUどれから始めてもマニュアル、入門書には書いてると思う。
553デフォルトの名無しさん
2019/11/29(金) 14:38:26.36ID:I3FFiKl3 JA、JB命令などは普通に使ってもJCを使うことはあまりない
554デフォルトの名無しさん
2019/11/29(金) 15:12:01.44ID:YkvT9y9m >>551
x86なんかキャリーフラグじゃない別のフラグを使った加算とか
歪んだ方向に行ってる
SIMDによる並列化プログラムも
フラグは単なるループ条件くらいにしか使わん
maskレジスタがその役目を継ぐ
x86なんかキャリーフラグじゃない別のフラグを使った加算とか
歪んだ方向に行ってる
SIMDによる並列化プログラムも
フラグは単なるループ条件くらいにしか使わん
maskレジスタがその役目を継ぐ
555デフォルトの名無しさん
2019/11/29(金) 16:58:01.66ID:kFqrise0 555
556デフォルトの名無しさん
2019/11/29(金) 18:54:08.05ID:9qxidx0X キャリーフラグを持たないアーキテクチャ・・・
MIPS?PPC?IA-64?死屍累々じゃねーかw
MIPS?PPC?IA-64?死屍累々じゃねーかw
557デフォルトの名無しさん
2019/11/29(金) 19:13:07.84ID:K9qn0Fk+ >>545
>フラグはアウトオブオーダーの妨げになるし
>並列化も出来ないから
また嘘書いてやがる
Core iプロセッサはフラグがあってもアウトオブオーダーしまくりですが?
アウトオブオーダーを正しく理解してたら絶対にこんなことは書かない
分岐も、投機実行で大凡はカバーされるということになっている
フラグの問題は、元の機械語の並べ方に制約が生じるだけで、アウトオブオーダー実行には関係ない
アウトオブオーダーを妨げるケースでも、元のCISCの挙動に合わせるためで、アウトオブオーダーが
関係しているのではない
>SIMDによる並列化プログラムも
>フラグは単なるループ条件くらいにしか使わん
>maskレジスタがその役目を継ぐ
これもまともに理解してないからこそ書ける内容だな
Pen Proになってアウトオブオーダーが使えるようになった時にcmovが導入されたし、
「単なるループ条件」でも投機実行が必要なんだが?
ここまで酷いとお前に語る資格はないよ
>フラグはアウトオブオーダーの妨げになるし
>並列化も出来ないから
また嘘書いてやがる
Core iプロセッサはフラグがあってもアウトオブオーダーしまくりですが?
アウトオブオーダーを正しく理解してたら絶対にこんなことは書かない
分岐も、投機実行で大凡はカバーされるということになっている
フラグの問題は、元の機械語の並べ方に制約が生じるだけで、アウトオブオーダー実行には関係ない
アウトオブオーダーを妨げるケースでも、元のCISCの挙動に合わせるためで、アウトオブオーダーが
関係しているのではない
>SIMDによる並列化プログラムも
>フラグは単なるループ条件くらいにしか使わん
>maskレジスタがその役目を継ぐ
これもまともに理解してないからこそ書ける内容だな
Pen Proになってアウトオブオーダーが使えるようになった時にcmovが導入されたし、
「単なるループ条件」でも投機実行が必要なんだが?
ここまで酷いとお前に語る資格はないよ
558デフォルトの名無しさん
2019/11/29(金) 19:39:22.16ID:4DEcYZGM アウトオブオーダーの妨げの意味がわからんのだね
なんでx86に変な命令があるのか考えてみ
なんでx86に変な命令があるのか考えてみ
559デフォルトの名無しさん
2019/11/29(金) 19:42:57.97ID:4DEcYZGM フラグは本来依存性の無い処理まで依存性が出てくる
フラグが共通だから
レジスタのようにフラグが複数セットあって指定出来ないとダメ
そらがmaskレジスタであったりx86の変な命令であったり
フラグが共通だから
レジスタのようにフラグが複数セットあって指定出来ないとダメ
そらがmaskレジスタであったりx86の変な命令であったり
560デフォルトの名無しさん
2019/11/29(金) 20:21:52.83ID:K9qn0Fk+ >>548,549
ID:YkvT9y9mがID変えたのか、別人なのかどっちだ?
アウトオブオーダーってのは、真の依存関係にない部分を抽出して同時に実行するっていう
アーキテクチャーだ
ループの2周目以降は前の分岐に依存しているから、本来は順番にしか実行できない
しかし、分岐は数値演算と違って結果のパターンが極めて限定されているので、
決め打ちで一時的に依存関係を無視して処理を進めるのが投機実行だ
アウトオブオーダー実行にはフラグレジスタの存在など関係なく、結果に依存関係が
あるかどうかが問題なんだよ
そんなことも理解せずに語ってたのかって言ってんだよ
ID:YkvT9y9mがID変えたのか、別人なのかどっちだ?
アウトオブオーダーってのは、真の依存関係にない部分を抽出して同時に実行するっていう
アーキテクチャーだ
ループの2周目以降は前の分岐に依存しているから、本来は順番にしか実行できない
しかし、分岐は数値演算と違って結果のパターンが極めて限定されているので、
決め打ちで一時的に依存関係を無視して処理を進めるのが投機実行だ
アウトオブオーダー実行にはフラグレジスタの存在など関係なく、結果に依存関係が
あるかどうかが問題なんだよ
そんなことも理解せずに語ってたのかって言ってんだよ
561デフォルトの名無しさん
2019/11/29(金) 20:34:10.69ID:4DEcYZGM フラグを使う演算だと依存関係が出るって言ってんの
関係ない演算でもフラグのせいで依存関係が出る
同じフラグを使うから
関係ない演算でもフラグのせいで依存関係が出る
同じフラグを使うから
562デフォルトの名無しさん
2019/11/29(金) 20:35:56.20ID:4DEcYZGM これで3回目だが...
x86の変なフラグを使う歪んだ命令は何のため?
x86の変なフラグを使う歪んだ命令は何のため?
563デフォルトの名無しさん
2019/11/29(金) 20:58:00.49ID:K9qn0Fk+ jaもjbもキャリーやゼロや符号の論理演算で表現されるのに、どうしてキャリーフラグが
どうのって話になってんの?
>>561
お前がアウトオブオーダーを理解できてないのはわかった
>フラグを使う演算だと依存関係が出るって言ってんの
>関係ない演算でもフラグのせいで依存関係が出る
>同じフラグを使うから
やはり論理レジスタと物理レジスタの理解も出来てないな
フラグを格納できるレジスタが複数あろうがなかろうが、それは命令アーキテクチャの問題であって
アウトオブオーダーの問題ではない
これでどうしてアウトオブオーダーの妨げになるんだよ?
>x86の変なフラグを使う歪んだ命令は何のため?
その変な命令って何だよ?
どうのって話になってんの?
>>561
お前がアウトオブオーダーを理解できてないのはわかった
>フラグを使う演算だと依存関係が出るって言ってんの
>関係ない演算でもフラグのせいで依存関係が出る
>同じフラグを使うから
やはり論理レジスタと物理レジスタの理解も出来てないな
フラグを格納できるレジスタが複数あろうがなかろうが、それは命令アーキテクチャの問題であって
アウトオブオーダーの問題ではない
これでどうしてアウトオブオーダーの妨げになるんだよ?
>x86の変なフラグを使う歪んだ命令は何のため?
その変な命令って何だよ?
564デフォルトの名無しさん
2019/11/29(金) 21:18:44.73ID:4DEcYZGM 命令を調べて出直しておいで
565デフォルトの名無しさん
2019/11/29(金) 21:30:22.27ID:Mi7N2zYE >>552
なんか勘違いしてる。CYの使い方がわからないのではなく、使う場面が少ないからあまり意識しないんじゃないかということ。
なんか勘違いしてる。CYの使い方がわからないのではなく、使う場面が少ないからあまり意識しないんじゃないかということ。
566デフォルトの名無しさん
2019/11/29(金) 21:44:01.72ID:IDh/GqUP >>564
mips64
daddu $2,$4,$6 1clock目
sltu $8,$2,$4 1clock目
dext $8,$8,0,32 2clock目
daddu $3,$5,$7 1clock目
daddu $4,$8,$3 3clock目
3clock 演算回数 計5回 (加算3回、減算1回、シフト1回)
risc-v
add a7,a0,a2 1clock目
sltu a6,a7,a0 1clock目
add t1,a1,a3 1clock目
add a6,a6,t1 2clock目
2clock 演算回数 4回 (加算3回、減算1回)
amd64
add 1clock目
adc 2clock目
2clock 演算回数 2回(加算2回)
mips、risc-vは必死に並列化してるのに速くならない。
むしろキャリーがあったほうが無駄な演算回数が減り消費電力も減り、
演算器に空きができ、他の計算の余力を得ることになり、並列処理能力は上がることが分かる。
キミのいう依存関係が出てmipsのほうが速い例を挙げてほしい。
mips64
daddu $2,$4,$6 1clock目
sltu $8,$2,$4 1clock目
dext $8,$8,0,32 2clock目
daddu $3,$5,$7 1clock目
daddu $4,$8,$3 3clock目
3clock 演算回数 計5回 (加算3回、減算1回、シフト1回)
risc-v
add a7,a0,a2 1clock目
sltu a6,a7,a0 1clock目
add t1,a1,a3 1clock目
add a6,a6,t1 2clock目
2clock 演算回数 4回 (加算3回、減算1回)
amd64
add 1clock目
adc 2clock目
2clock 演算回数 2回(加算2回)
mips、risc-vは必死に並列化してるのに速くならない。
むしろキャリーがあったほうが無駄な演算回数が減り消費電力も減り、
演算器に空きができ、他の計算の余力を得ることになり、並列処理能力は上がることが分かる。
キミのいう依存関係が出てmipsのほうが速い例を挙げてほしい。
567デフォルトの名無しさん
2019/11/29(金) 21:59:54.67ID:/ptQUX0m568デフォルトの名無しさん
2019/11/30(土) 07:32:32.63ID:zk5zlAHc569デフォルトの名無しさん
2019/11/30(土) 07:35:49.37ID:zk5zlAHc MIPSの話が出るとすぐにキャリーフラグを連呼する例の人かな
彼は8bitCPUの話が好きみたいだが
もう、既に死んでる6502、Z80、6809、68Kあたりを挙げてるからすぐにわかる
彼は8bitCPUの話が好きみたいだが
もう、既に死んでる6502、Z80、6809、68Kあたりを挙げてるからすぐにわかる
570デフォルトの名無しさん
2019/11/30(土) 07:38:44.36ID:zk5zlAHc 8bitCPUなら多倍長演算はよく使うだろうが64bitCPUではほぼ出番がない
571デフォルトの名無しさん
2019/11/30(土) 07:45:40.61ID:xhEM6aVw572デフォルトの名無しさん
2019/11/30(土) 07:55:34.04ID:zk5zlAHc RISC-VならARMのCortex-A72より早いコアができたってさ
このクラスの性能のCPUはx86、POWER、ARM以外にないだろうに
SiFive readies U8-Series RISC-V core designs to compete with ARM's Cortex-A72 models
https://www.notebookcheck.net/SiFive-readies-U8-Series-RISC-V-core-designs-to-compete-with-ARM-s-Cortex-A72-models.440633.0.html
このクラスの性能のCPUはx86、POWER、ARM以外にないだろうに
SiFive readies U8-Series RISC-V core designs to compete with ARM's Cortex-A72 models
https://www.notebookcheck.net/SiFive-readies-U8-Series-RISC-V-core-designs-to-compete-with-ARM-s-Cortex-A72-models.440633.0.html
573デフォルトの名無しさん
2019/11/30(土) 08:04:40.62ID:zk5zlAHc >>571
別人の発言なのに敵視した人は誰でも同一人物だと思っちゃう人?
別人の発言なのに敵視した人は誰でも同一人物だと思っちゃう人?
574デフォルトの名無しさん
2019/11/30(土) 08:05:52.96ID:xhEM6aVw575デフォルトの名無しさん
2019/11/30(土) 08:10:23.93ID:zk5zlAHc RISC-Vの中国製チップを使ったマイコンボード手に入れたが、
普通にCortex-A7クラスのIPCがあってびっくりした
ARMと違ってRISC-Vなのでおそらく中国の半導体メーカーがコアの設計までしたんだろうな
RISC-Vならオープンソースのコアがあるから
中国の半導体メーカーでもそれを参考にして設計できるんだろうね
RISC-Vは中国やインドで推進してるから今後普及していくだろうね
普通にCortex-A7クラスのIPCがあってびっくりした
ARMと違ってRISC-Vなのでおそらく中国の半導体メーカーがコアの設計までしたんだろうな
RISC-Vならオープンソースのコアがあるから
中国の半導体メーカーでもそれを参考にして設計できるんだろうね
RISC-Vは中国やインドで推進してるから今後普及していくだろうね
576デフォルトの名無しさん
2019/11/30(土) 08:12:36.49ID:WebQyLi7 SIMD命令にキャリーフラグやADC/SBB/RCR/RCL命令が無いのが
演算としては使わないっていう証拠
こういった命令は昔のチープな環境のなごり
演算としては使わないっていう証拠
こういった命令は昔のチープな環境のなごり
577デフォルトの名無しさん
2019/11/30(土) 08:14:24.92ID:zk5zlAHc >>574
たとえば、
CMP EAX,10
JB hogehoge
こんなコードだと比較命令でフラグレジスタが変わるが
次の命令ですぐにフラグレジスタを参照してるってことじゃないの?
俺が発言したわけじゃないから知らんけど
たとえば、
CMP EAX,10
JB hogehoge
こんなコードだと比較命令でフラグレジスタが変わるが
次の命令ですぐにフラグレジスタを参照してるってことじゃないの?
俺が発言したわけじゃないから知らんけど
578デフォルトの名無しさん
2019/11/30(土) 08:25:28.29ID:xhEM6aVw579デフォルトの名無しさん
2019/11/30(土) 08:30:24.01ID:zk5zlAHc580デフォルトの名無しさん
2019/11/30(土) 08:33:19.07ID:zk5zlAHc そもそもキャリーフラグが有用なのは2進バイナリの多倍長演算の時だけ
64bitCPUではほぼ出番がない
64bitCPUではほぼ出番がない
581デフォルトの名無しさん
2019/11/30(土) 08:45:13.32ID:xhEM6aVw 挟むめないって挟む理由あるアルゴリズムなんて存在するか?
そんなコード書ける高級言語はないし。キミは一体RISCで何を計算したいんだ?
そんなコード書ける高級言語はないし。キミは一体RISCで何を計算したいんだ?
582デフォルトの名無しさん
2019/11/30(土) 09:00:24.68ID:zk5zlAHc アセンブラの話してるのになんで高級言語の話になるのかな?
MIPSならslt $2, $3, 11とジャンプ命令の間にほかの命令を挟めるってこと
MIPSならslt $2, $3, 11とジャンプ命令の間にほかの命令を挟めるってこと
583デフォルトの名無しさん
2019/11/30(土) 09:22:02.63ID:xhEM6aVw >>582
そうではない。挟まなきゃならない理由を聞いている。
それで並列化できなかったものが並列化可能なら例になるがそうではない。判定の前に命令書いても依存関係がなければ並列化される。
キミの例は可読性が悪くなる書き方ができるというだけで並列化できる例ではない。むしろMPSの欠点だ。
> フラグはアウトオブオーダーの妨げになるし並列化も出来ないから
の例を聞いてるんだよ。ひとつも例が出せてないじゃないか。
そうではない。挟まなきゃならない理由を聞いている。
それで並列化できなかったものが並列化可能なら例になるがそうではない。判定の前に命令書いても依存関係がなければ並列化される。
キミの例は可読性が悪くなる書き方ができるというだけで並列化できる例ではない。むしろMPSの欠点だ。
> フラグはアウトオブオーダーの妨げになるし並列化も出来ないから
の例を聞いてるんだよ。ひとつも例が出せてないじゃないか。
584デフォルトの名無しさん
2019/11/30(土) 09:40:23.31ID:zk5zlAHc 演算のたびにフラグレジスタが変化するのは無駄だとは思うけどね
特にアドレス計算のたびにフラグレジスタが変化するのはうっとうしい
ARMだと加算減算命令はフラグレジスタが変化するものと変化しないのと2種類用意されてるね
特にアドレス計算のたびにフラグレジスタが変化するのはうっとうしい
ARMだと加算減算命令はフラグレジスタが変化するものと変化しないのと2種類用意されてるね
585デフォルトの名無しさん
2019/11/30(土) 09:43:31.34ID:zk5zlAHc しかし、キャリーフラグの話題でここまでスレ伸ばすのはすごいね
8bitのAVR信者っぽいんだけど
8bitだとキャリーフラグがないと何もできないからね
8bitのAVR信者っぽいんだけど
8bitだとキャリーフラグがないと何もできないからね
586デフォルトの名無しさん
2019/11/30(土) 09:53:10.63ID:xhEM6aVw 結局、自分から言い出しといて挟まなきゃならない理由も説明してくれないのか。
まだほとんどコード書いたことない初心者なんだね^^
まだほとんどコード書いたことない初心者なんだね^^
587デフォルトの名無しさん
2019/11/30(土) 11:02:33.57ID:WebQyLi7 間に挟みたい場面なんていくらでもあるだろうに
少しは考えたら?
少しは考えたら?
588デフォルトの名無しさん
2019/11/30(土) 11:06:05.90ID:xhEM6aVw589デフォルトの名無しさん
2019/11/30(土) 11:18:54.45ID:zk5zlAHc パイプラインがストールするとか言うから
MIPSやRISC-Vならslt命令とbne命令の間に他の命令を挟めるよと言っただけ
自分で発言を誘っておいて意味もわからないんだな
MIPSやRISC-Vならslt命令とbne命令の間に他の命令を挟めるよと言っただけ
自分で発言を誘っておいて意味もわからないんだな
590デフォルトの名無しさん
2019/11/30(土) 11:28:29.70ID:xhEM6aVw >>589
頓珍漢。ストールするのは条件ジャンプだから。挟んでもその後でmipsはストールする。
挟まなきゃならない理由の説明になってなし、並列化できるでなきいの例でもなんでもない。
話戻すよ。mipsは並列化できてフラグありCPUで並列化できない例を挙げてと言ってるんだよ。
頓珍漢。ストールするのは条件ジャンプだから。挟んでもその後でmipsはストールする。
挟まなきゃならない理由の説明になってなし、並列化できるでなきいの例でもなんでもない。
話戻すよ。mipsは並列化できてフラグありCPUで並列化できない例を挙げてと言ってるんだよ。
591デフォルトの名無しさん
2019/11/30(土) 11:30:10.99ID:zk5zlAHc まあ、いつものAVRの人の荒らしだからまともに答えるだけ無駄
592デフォルトの名無しさん
2019/11/30(土) 11:41:14.59ID:WebQyLi7 x86のイビツな命令は調べたの?
593デフォルトの名無しさん
2019/11/30(土) 11:42:25.43ID:WebQyLi7 SIMD用キャリーフラグがあるCPUってある?
594デフォルトの名無しさん
2019/11/30(土) 11:49:35.35ID:xhEM6aVw >>591
たった一つの例が全然例でなかったのに勝利宣言か。だいたいAVRもキミの好きなRISCだろう。
cmp
jb
並列化できない!! ←mipsでもできません
cmp
add
jb
mipsならこんなことができる!!
↑
挟む理由は別になし。可読性が低下するだけ。
同じことしたいならadd、cmp、jbの順に書けばいいだけ。これで並列可。
しかもmipsのほうが遅いという。
たった一つの例が全然例でなかったのに勝利宣言か。だいたいAVRもキミの好きなRISCだろう。
cmp
jb
並列化できない!! ←mipsでもできません
cmp
add
jb
mipsならこんなことができる!!
↑
挟む理由は別になし。可読性が低下するだけ。
同じことしたいならadd、cmp、jbの順に書けばいいだけ。これで並列可。
しかもmipsのほうが遅いという。
595デフォルトの名無しさん
2019/11/30(土) 12:20:15.39ID:WebQyLi7 cmpに時間がかかる(可能性がある)なら挟む
分岐なのでcmp結果はなるべく早く欲しい
当然命令順が速い方が実行順が速い可能性が高くなる
アセンブラに可読性?
99.99%のコードはコンパイラを使うから
そもそも可読性を考えて命令を作らない
分岐なのでcmp結果はなるべく早く欲しい
当然命令順が速い方が実行順が速い可能性が高くなる
アセンブラに可読性?
99.99%のコードはコンパイラを使うから
そもそも可読性を考えて命令を作らない
596デフォルトの名無しさん
2019/11/30(土) 12:54:50.65ID:WebQyLi7 キャリーフラグの典型的な用途
多倍長整数の加算
ADCを連続で行うが
この間にキャリーフラグを使う命令は入れられない
今時のCPUは整数命令を4個同時に実行出来るので
間に命令をいれないと性能の1/4しか活かせない
性能を活かすには4個パラにするか、
多倍長加算以外の処理を入れることになるが
キャリーフラグのせいでこれが出来ない
最大限に最適化する場合はSIMD命令を使うのだが
これにもキャリーフラグなんてものは無い
多倍長整数の加算
ADCを連続で行うが
この間にキャリーフラグを使う命令は入れられない
今時のCPUは整数命令を4個同時に実行出来るので
間に命令をいれないと性能の1/4しか活かせない
性能を活かすには4個パラにするか、
多倍長加算以外の処理を入れることになるが
キャリーフラグのせいでこれが出来ない
最大限に最適化する場合はSIMD命令を使うのだが
これにもキャリーフラグなんてものは無い
597デフォルトの名無しさん
2019/11/30(土) 12:58:12.03ID:+5qlZFtZ 現状RISC-Vの性能はAMD64に及ばなくね?理論がどうであれ実証できなきゃ絵に描いた餅よ
IA-32は長らくクソと言わ続けているがIntelとAMDが競争しているおかげか
そのハンデをねじ伏せいまだに高性能プロセッサの一角だしな
IA-32は長らくクソと言わ続けているがIntelとAMDが競争しているおかげか
そのハンデをねじ伏せいまだに高性能プロセッサの一角だしな
598デフォルトの名無しさん
2019/11/30(土) 13:04:28.68ID:WebQyLi7 こんな極端な例じゃなくても
実際の実行順に近い順番で命令を書く方が
アウトオブオーダーの制約に引っ掛かりにくく
性能を活かせやすい
実際の実行順で
キャリーフラグを変更する命令と
キャリーフラグを使う命令
の間に何も命令を実行しないなんてことは非常にマレ
あったとすれば、
それはCPUの能力を全く活かしてない糞コード
実際の実行順に近い順番で命令を書く方が
アウトオブオーダーの制約に引っ掛かりにくく
性能を活かせやすい
実際の実行順で
キャリーフラグを変更する命令と
キャリーフラグを使う命令
の間に何も命令を実行しないなんてことは非常にマレ
あったとすれば、
それはCPUの能力を全く活かしてない糞コード
599デフォルトの名無しさん
2019/11/30(土) 13:09:58.22ID:xhEM6aVw >>595
> cmpに時間がかかる(可能性がある)なら挟む
また理由は書かないのか。まあ理由は分からないがMIPSはそんな可能性があるとは遅くて大変だな。
インテルの実装は速くなることはあっても遅くはならないから。いつになったらフラグで遅くなる例を出してくれるんだか。
まさか条件分岐でインテルやARMに勝つ気じゃないよね?
> cmpに時間がかかる(可能性がある)なら挟む
また理由は書かないのか。まあ理由は分からないがMIPSはそんな可能性があるとは遅くて大変だな。
インテルの実装は速くなることはあっても遅くはならないから。いつになったらフラグで遅くなる例を出してくれるんだか。
まさか条件分岐でインテルやARMに勝つ気じゃないよね?
600デフォルトの名無しさん
2019/11/30(土) 13:31:31.66ID:K1Ueg6YG MIPS vs ARM (またはx86) だと思ってる時点で話にならん
601デフォルトの名無しさん
2019/11/30(土) 13:33:55.49ID:xhEM6aVw602デフォルトの名無しさん
2019/11/30(土) 15:27:59.62ID:rGr6foFe いつものAVR信者だからかまっちゃダメ
MIPSと聞くと毎回同じようにキャリーフラグの話を始める
いつも自分が正義だと思い込んでて他人の都合の悪い意見は全く無視するからね
http://rio2016.5ch.net/test/read.cgi/denki/1462177958/134
134 :774ワット発電中さん [↓] :2019/11/30(土) 14:53:33.69 ID:IRFNBB8m.net
またMIPS君が他の板で暴れて論破された模様TT
フラグで遅くなる例を出せと言われて一つも出せなかったらしい。
MIPSと聞くと毎回同じようにキャリーフラグの話を始める
いつも自分が正義だと思い込んでて他人の都合の悪い意見は全く無視するからね
http://rio2016.5ch.net/test/read.cgi/denki/1462177958/134
134 :774ワット発電中さん [↓] :2019/11/30(土) 14:53:33.69 ID:IRFNBB8m.net
またMIPS君が他の板で暴れて論破された模様TT
フラグで遅くなる例を出せと言われて一つも出せなかったらしい。
603デフォルトの名無しさん
2019/11/30(土) 15:30:00.80ID:AFPNe0zJ >>574
そりゃ逃げ回るでしょ、アウトオブオーダーがどんな仕組みで並列に実行できるのか理解してないんだからw
こんなこと書いてるからな
>フラグは本来依存性の無い処理まで依存性が出てくる
>フラグが共通だから
これのどこがアウトオブオーダーによる制限なんだよw
間に挟めないのは元の命令アーキテクチャによる制限だって書いたよな
>>596
>今時のCPUは整数命令を4個同時に実行出来るので
>間に命令をいれないと性能の1/4しか活かせない
また出まかせをw
ここ数年インテルがリオーダーバッファのサイズとか強化してるのは何でだよ?
メモリアクセスのレイテンシの影響を軽減するためだろ
そういう状態ではカウンタとかポインタのインクリメントみたいな処理は前倒しで実行されるから、
間に命令を挟んだのと同じことになるよな
そりゃ逃げ回るでしょ、アウトオブオーダーがどんな仕組みで並列に実行できるのか理解してないんだからw
こんなこと書いてるからな
>フラグは本来依存性の無い処理まで依存性が出てくる
>フラグが共通だから
これのどこがアウトオブオーダーによる制限なんだよw
間に挟めないのは元の命令アーキテクチャによる制限だって書いたよな
>>596
>今時のCPUは整数命令を4個同時に実行出来るので
>間に命令をいれないと性能の1/4しか活かせない
また出まかせをw
ここ数年インテルがリオーダーバッファのサイズとか強化してるのは何でだよ?
メモリアクセスのレイテンシの影響を軽減するためだろ
そういう状態ではカウンタとかポインタのインクリメントみたいな処理は前倒しで実行されるから、
間に命令を挟んだのと同じことになるよな
604デフォルトの名無しさん
2019/11/30(土) 15:44:48.54ID:WebQyLi7 分岐に必要な命令を先に実行するほど頭は良くない
単に実行出来る命令から実行するだけ
だからコンパイラがわざわざ順番を変える
フラグのせいでそれに大きな制限がつく
アウトオブオーダーが完璧ならコンパイラがわざわざ順番を変えたりループを展開したりしないから
同じ命令を使えば誰が書いても同じパフォーマンス
そこまで時代は進んでない
だからCコードで最適化してコンパイラが最適化してCPUが最適化してるの
フラグは8bitとか16bitとか、
非常に規模の小さなCPUにとっては便利だが
規模の大きなCPUでは足かせになる
使用頻度は減って
使用用途はほとんど分岐くらい
レジスタの数も少ないと問題だろ?
フラグも同じ
単に実行出来る命令から実行するだけ
だからコンパイラがわざわざ順番を変える
フラグのせいでそれに大きな制限がつく
アウトオブオーダーが完璧ならコンパイラがわざわざ順番を変えたりループを展開したりしないから
同じ命令を使えば誰が書いても同じパフォーマンス
そこまで時代は進んでない
だからCコードで最適化してコンパイラが最適化してCPUが最適化してるの
フラグは8bitとか16bitとか、
非常に規模の小さなCPUにとっては便利だが
規模の大きなCPUでは足かせになる
使用頻度は減って
使用用途はほとんど分岐くらい
レジスタの数も少ないと問題だろ?
フラグも同じ
605デフォルトの名無しさん
2019/11/30(土) 15:46:59.54ID:WebQyLi7606デフォルトの名無しさん
2019/11/30(土) 15:49:53.66ID:WebQyLi7 RCR/RCL による多倍長の1ビットシフトなんか最悪だ
依存性が途切れないので1クロックに1回しか出来ない
ADCもSBBも依存性が途切れないから
もっと頭の良い方法を使うんだけど
依存性が途切れないので1クロックに1回しか出来ない
ADCもSBBも依存性が途切れないから
もっと頭の良い方法を使うんだけど
607デフォルトの名無しさん
2019/11/30(土) 15:50:53.74ID:WebQyLi7 まあそもそも可読性とか言ってる時点で話にならん
アセンブラなんか使わないで素直にCで書いてな
アセンブラなんか使わないで素直にCで書いてな
608デフォルトの名無しさん
2019/11/30(土) 15:53:07.85ID:AFPNe0zJ ID:zk5zlAHcはID:4DEcYZGMやID:zk5zlAHcなんて擁護すると見識を疑われるぞ!
>>604
うわっ、酷っ!
>レジスタの数も少ないと問題だろ?
>フラグも同じ
結局これしか理解できてないから壮大な妄想を展開してたのかよw
>>604
うわっ、酷っ!
>レジスタの数も少ないと問題だろ?
>フラグも同じ
結局これしか理解できてないから壮大な妄想を展開してたのかよw
609デフォルトの名無しさん
2019/11/30(土) 15:54:01.77ID:AFPNe0zJ ID:4DEcYZGMとID:WebQyLi7
だった
だった
610デフォルトの名無しさん
2019/11/30(土) 15:54:06.44ID:WebQyLi7 大体、
普段多倍長なんか使わんだろ
頻繁に演算でフラグを使う場面ていつだよ?
64bitありゃ99%は問題ないだろ
フラグの用途のほとんどが条件分岐だろうが
SIMDにフラグが無い理由を少しは考えろ
普段多倍長なんか使わんだろ
頻繁に演算でフラグを使う場面ていつだよ?
64bitありゃ99%は問題ないだろ
フラグの用途のほとんどが条件分岐だろうが
SIMDにフラグが無い理由を少しは考えろ
611デフォルトの名無しさん
2019/11/30(土) 15:57:07.46ID:AFPNe0zJ >>606
>RCR/RCL による多倍長の1ビットシフトなんか最悪だ
>依存性が途切れないので1クロックに1回しか出来ない
これも突っ込みどころのある発言w
どうして依存性が切れないのか、やっぱり理解できてない
>RCR/RCL による多倍長の1ビットシフトなんか最悪だ
>依存性が途切れないので1クロックに1回しか出来ない
これも突っ込みどころのある発言w
どうして依存性が切れないのか、やっぱり理解できてない
612デフォルトの名無しさん
2019/11/30(土) 15:59:39.71ID:WebQyLi7 1000ワードの多倍長加算を100個
データはキャュシュにあるとして
どんなコードにする?
糞遅いコードしか書けないだろうね
データはキャュシュにあるとして
どんなコードにする?
糞遅いコードしか書けないだろうね
613デフォルトの名無しさん
2019/11/30(土) 16:00:43.39ID:WebQyLi7614デフォルトの名無しさん
2019/11/30(土) 16:01:19.45ID:WebQyLi7 レベルが低すぎて会話にならない
615デフォルトの名無しさん
2019/11/30(土) 16:05:29.45ID:AFPNe0zJ どうして依存性が切れないのか理解できてないのがレベルが低いって言ってんだよ
WAW依存とか理解してるか?
WAW依存とか理解してるか?
616デフォルトの名無しさん
2019/11/30(土) 16:29:11.13ID:WebQyLi7 >>612 の擬似コード
for (int i = 0 ; i < 100 ; i++){
. . CLC
. . for (int j = 0 ; j < 1000 ; j++){
. . . . ADC dest[i][j], src[i][j]
. . }
}
メモリアクセスや制御時間がゼロとしても
100 x 1000クロックかかる
ADCが前のADCの結果に依存するから
順番に処理をするしかない
RCL/RCRを使ったシフトも同じ
for (int i = 0 ; i < 100 ; i++){
. . CLC
. . for (int j = 0 ; j < 1000 ; j++){
. . . . ADC dest[i][j], src[i][j]
. . }
}
メモリアクセスや制御時間がゼロとしても
100 x 1000クロックかかる
ADCが前のADCの結果に依存するから
順番に処理をするしかない
RCL/RCRを使ったシフトも同じ
617デフォルトの名無しさん
2019/11/30(土) 16:32:15.54ID:WebQyLi7 これはコンパイラの最適化やCPUのアウトオブオーダーでは解決出来ない
アセンブラで書こうがCで書こうが
頭が悪い人にとってはこれが限界
アセンブラで書こうがCで書こうが
頭が悪い人にとってはこれが限界
618デフォルトの名無しさん
2019/11/30(土) 17:01:55.28ID:rGr6foFe ただの荒らしにマジレスしても疲れるだけだよ
619デフォルトの名無しさん
2019/11/30(土) 17:22:23.36ID:xhEM6aVw そういうキャリーが必要な、前の計算結果が必要で依存する計算は、
キャリーがないCPUだとさらに効率は悪化するから例として意味がない。
128bitを1bit左シフト
SHL
RCL
mips64だとどういうコードですか?
andi
srl
sll
sll
or
みたいな? 大変でつね。他に便利な命令でもあるんですかね?RISCに対して失礼な質問でしたね^^
キャリーがないCPUだとさらに効率は悪化するから例として意味がない。
128bitを1bit左シフト
SHL
RCL
mips64だとどういうコードですか?
andi
srl
sll
sll
or
みたいな? 大変でつね。他に便利な命令でもあるんですかね?RISCに対して失礼な質問でしたね^^
620デフォルトの名無しさん
2019/11/30(土) 17:32:16.88ID:8+8CeiWg > 頭が悪い人にとってはこれが限界
ほんとそのまんまでわらた
依存性を減らす、隠蔽するのが最適化の肝
ちょっとは考えてね
ほんとそのまんまでわらた
依存性を減らす、隠蔽するのが最適化の肝
ちょっとは考えてね
621デフォルトの名無しさん
2019/11/30(土) 17:36:12.41ID:8+8CeiWg622デフォルトの名無しさん
2019/11/30(土) 17:37:47.29ID:rGr6foFe それって1bit以外のシフトならどうなるの?
623デフォルトの名無しさん
2019/11/30(土) 17:45:13.95ID:8+8CeiWg キャリーフラグの人は多倍長1ビットシフトを繰り返す
普通の人はバレルシフタをうまく使う
普通の人はバレルシフタをうまく使う
624デフォルトの名無しさん
2019/11/30(土) 17:52:27.94ID:21OIT27J 一度に1000回もADCするとかよほど暇なアプリケーションなのだろうな
マイコンのADCと仮定すると速い物でも計0.5〜1msecくらいかかるだろう
単に移動平均が欲しいだけなら必要なコストはADC変換1回に付き加減算各1回+メモリアクセスですむんだし
マイコンのADCと仮定すると速い物でも計0.5〜1msecくらいかかるだろう
単に移動平均が欲しいだけなら必要なコストはADC変換1回に付き加減算各1回+メモリアクセスですむんだし
625デフォルトの名無しさん
2019/11/30(土) 19:36:02.39ID:8+8CeiWg 何で移動平均が突然?
多倍長の話だろ?
そもそも多倍長なんか普通は使わない
普通は64bitで収まる
だからキャリーフラグを使った足し算なんて普通はしない
キャリーフラグを使った演算は
8bit、16bit時代の、遅いCPU時代のなごりだ
多倍長の話だろ?
そもそも多倍長なんか普通は使わない
普通は64bitで収まる
だからキャリーフラグを使った足し算なんて普通はしない
キャリーフラグを使った演算は
8bit、16bit時代の、遅いCPU時代のなごりだ
626デフォルトの名無しさん
2019/11/30(土) 21:00:54.84ID:xhEM6aVw >>625
ARMは最初から32bitだし、AVRに至っては32bit時代に新規に開発された8bitCPUだし、
共に市場で成功したRISC CPUである。キミがキャリー使わないのは単にコード書かないからに過ぎない。
Cでif文でも書けばコンパイラが必然的に使ってしまう。
ARMは最初から32bitだし、AVRに至っては32bit時代に新規に開発された8bitCPUだし、
共に市場で成功したRISC CPUである。キミがキャリー使わないのは単にコード書かないからに過ぎない。
Cでif文でも書けばコンパイラが必然的に使ってしまう。
627デフォルトの名無しさん
2019/11/30(土) 21:04:16.02ID:xhEM6aVw >>623
さて、キミの任意bitシフトのバレルシフタのコードみせてもらおう。verilogでいいよ。
さて、キミの任意bitシフトのバレルシフタのコードみせてもらおう。verilogでいいよ。
628デフォルトの名無しさん
2019/11/30(土) 22:20:20.00ID:jbs9cucn629デフォルトの名無しさん
2019/11/30(土) 22:23:01.70ID:jbs9cucn630デフォルトの名無しさん
2019/11/30(土) 22:31:00.07ID:AFPNe0zJ >そもそも多倍長なんか普通は使わない
とか書いておきながら100個の多倍長とか、ずいぶんと極端な例を持ち出すことw
ローテート命令が依存性を抱えてる理由に即答することもできずに、別の話題で誤魔化そうとしてるから
あんたがアウトオブオーダーをまともに理解してないのは確定的だな
これで究極の最適化だのほざいてたのかよw
とか書いておきながら100個の多倍長とか、ずいぶんと極端な例を持ち出すことw
ローテート命令が依存性を抱えてる理由に即答することもできずに、別の話題で誤魔化そうとしてるから
あんたがアウトオブオーダーをまともに理解してないのは確定的だな
これで究極の最適化だのほざいてたのかよw
631デフォルトの名無しさん
2019/11/30(土) 22:33:09.34ID:jbs9cucn 煽れば答えがもらえると思うのは間違い
レベルが違い過ぎて話にならんから無視するぞ
レベルが違い過ぎて話にならんから無視するぞ
632デフォルトの名無しさん
2019/11/30(土) 22:34:55.48ID:FaWuMeWQ >>607
「話にならん」が口癖の人には悪いけど、可読性は非常に大事。
MASMならマクロが使えるから、定型的な処理はマクロで書いておけばその処理が必要な部分は1行で書けるし、
if-elseマクロを使うだけでもだいぶわかりやすくなる。
http://shaw.la.coocan.jp/masm/control.php
特に他人が書いたソースをいじらないといけないときは可読性大事。修正や変更の手間が大幅に省ける。
「話にならん」が口癖の人には悪いけど、可読性は非常に大事。
MASMならマクロが使えるから、定型的な処理はマクロで書いておけばその処理が必要な部分は1行で書けるし、
if-elseマクロを使うだけでもだいぶわかりやすくなる。
http://shaw.la.coocan.jp/masm/control.php
特に他人が書いたソースをいじらないといけないときは可読性大事。修正や変更の手間が大幅に省ける。
633デフォルトの名無しさん
2019/11/30(土) 22:37:24.82ID:xhEM6aVw >>629
頓珍漢なレスにマジレスしてやったらそれを理解せず頓珍漢なこと言われてもだな。
それともMIPSは1bitシフトとバレルシフタと命令が別なのかい? RISCなのにw
> キャリーフラグの人は多倍長1ビットシフトを繰り返す
> 普通の人はバレルシフタをうまく使う
とにかく煽りではなくコード見せてよ。
バレルシフタを上手くつかった任意bitのシフトを。キミは普通の人なんだろ?
頓珍漢なレスにマジレスしてやったらそれを理解せず頓珍漢なこと言われてもだな。
それともMIPSは1bitシフトとバレルシフタと命令が別なのかい? RISCなのにw
> キャリーフラグの人は多倍長1ビットシフトを繰り返す
> 普通の人はバレルシフタをうまく使う
とにかく煽りではなくコード見せてよ。
バレルシフタを上手くつかった任意bitのシフトを。キミは普通の人なんだろ?
634デフォルトの名無しさん
2019/11/30(土) 22:44:56.42ID:AFPNe0zJ635デフォルトの名無しさん
2019/12/01(日) 01:20:15.72ID:npZTl1ra 100個の多倍長の配列なんて極端な例を持ち出さなきゃ、普通にアウトオブオーダー実行されるってことだよな
でなきゃそんな欠陥CPUなんてスパコンで使うはずないだろうに
mov edx, 1
…
xor eax, eax
キャリーを変化させたい命令
cmovc eax, edx
ってやりゃ、キャリーフラグの結果をGPRに反映できるはずだから、以降は機械語の制限による
依存は切り離せるはずだよな
でなきゃそんな欠陥CPUなんてスパコンで使うはずないだろうに
mov edx, 1
…
xor eax, eax
キャリーを変化させたい命令
cmovc eax, edx
ってやりゃ、キャリーフラグの結果をGPRに反映できるはずだから、以降は機械語の制限による
依存は切り離せるはずだよな
636デフォルトの名無しさん
2019/12/01(日) 01:44:07.93ID:npZTl1ra cmovcじゃなく、
adc eax, 0
でもいいか
こっちの方が余計なレジスタ使わなくていいし
adc eax, 0
でもいいか
こっちの方が余計なレジスタ使わなくていいし
637デフォルトの名無しさん
2019/12/01(日) 02:42:43.59ID:rpSiZ7Ms コンパイラに出力させると
例えば、15bitの左シフトはこんな感じ
$3:$2←$5:$4 << 15
dsrl $2,$4,49
dsll $3,$5,15
or $3,$2,$3
dsll $2,$4,15
risc-vのRV64GCだとこう
a1:a0←a1:a0 << 15
srl a5,a0,49
sll a1,a1,15
sll a0,a0,15
or a1,a5,a1
arm64だとこう
x1:x0←x1:x0 << 15
mov x2, x0
lsl x0, x0, 15
extr x1, x1, x2, 49
例えば、15bitの左シフトはこんな感じ
$3:$2←$5:$4 << 15
dsrl $2,$4,49
dsll $3,$5,15
or $3,$2,$3
dsll $2,$4,15
risc-vのRV64GCだとこう
a1:a0←a1:a0 << 15
srl a5,a0,49
sll a1,a1,15
sll a0,a0,15
or a1,a5,a1
arm64だとこう
x1:x0←x1:x0 << 15
mov x2, x0
lsl x0, x0, 15
extr x1, x1, x2, 49
638デフォルトの名無しさん
2019/12/01(日) 02:43:56.72ID:rpSiZ7Ms 任意のシフトはこんな感じ
$3:$2←$5:$4 << $6
sll $2,$6,0
dsrl $3,$4,1
nor $7,$0,$6
dsrl $7,$3,$7
dsll $3,$5,$2
andi $6,$6,0x40
dsll $2,$4,$2
or $3,$7,$3
movn $3,$2,$6
movn $2,$0,$6
risc-vのRV64GCだとこう
a1:a0←a1:a0 << a2
and a5,a2,64
beqz a5,.L1
sll a1,a0,a2
li a0,0
jal zero, .L2
.L1:
srl a5,a0,1
not a4,a2
srl a5,a5,a4
sll a1,a1,a2
or a1,a5,a1
sll a0,a0,a2
.L2:
$3:$2←$5:$4 << $6
sll $2,$6,0
dsrl $3,$4,1
nor $7,$0,$6
dsrl $7,$3,$7
dsll $3,$5,$2
andi $6,$6,0x40
dsll $2,$4,$2
or $3,$7,$3
movn $3,$2,$6
movn $2,$0,$6
risc-vのRV64GCだとこう
a1:a0←a1:a0 << a2
and a5,a2,64
beqz a5,.L1
sll a1,a0,a2
li a0,0
jal zero, .L2
.L1:
srl a5,a0,1
not a4,a2
srl a5,a5,a4
sll a1,a1,a2
or a1,a5,a1
sll a0,a0,a2
.L2:
639デフォルトの名無しさん
2019/12/01(日) 02:44:18.13ID:rpSiZ7Ms arm64だとこう
x1:x0←x1:x0 << w2
mov w4, 63
sub w5, w4, w2
lsr x4, x0, 1
sub w3, w2, #64
cmp w3, 0
lsl x1, x1, x2
lsr x4, x4, x5
orr x1, x4, x1
lsl x4, x0, x3
csel x1, x4, x1, ge
lsl x0, x0, x2
csel x0, x0, xzr, lt
x1:x0←x1:x0 << w2
mov w4, 63
sub w5, w4, w2
lsr x4, x0, 1
sub w3, w2, #64
cmp w3, 0
lsl x1, x1, x2
lsr x4, x4, x5
orr x1, x4, x1
lsl x4, x0, x3
csel x1, x4, x1, ge
lsl x0, x0, x2
csel x0, x0, xzr, lt
640デフォルトの名無しさん
2019/12/01(日) 11:18:31.61ID:sKSeAmO2 そういえば最近のx86は
典型的な条件ジャンプは
内部的に比較やテストとあわせて1個のuOP命令になる
内部的にはMIPSの条件ジャンプをリッチにした感じ
比較とブランチで2命令も費やしてたら
パフォーマンス的に問題だからね
分岐でも演算でも、
キャリーフラグの出番はもうほとんどない
典型的な条件ジャンプは
内部的に比較やテストとあわせて1個のuOP命令になる
内部的にはMIPSの条件ジャンプをリッチにした感じ
比較とブランチで2命令も費やしてたら
パフォーマンス的に問題だからね
分岐でも演算でも、
キャリーフラグの出番はもうほとんどない
641デフォルトの名無しさん
2019/12/01(日) 12:25:49.37ID:rpSiZ7Ms Intel® 64 and IA-32 ArchitecturesOptimization Reference Manual
64-ia-32-architectures-optimization-manual.pdf
248966-033June 2016
109ページ目3-12の3.4.2.2 Optimizing for Macro-fusionに書かれてるね
リンクはNGワードで貼れなかったのでググッてね
64-ia-32-architectures-optimization-manual.pdf
248966-033June 2016
109ページ目3-12の3.4.2.2 Optimizing for Macro-fusionに書かれてるね
リンクはNGワードで貼れなかったのでググッてね
642デフォルトの名無しさん
2019/12/01(日) 12:29:50.17ID:rpSiZ7Ms 最新のやつだと貼れるかな?
https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf
130ページ目3-12の3.4.2.2 Optimizing for Macro-fusionに書かれてるね
https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf
130ページ目3-12の3.4.2.2 Optimizing for Macro-fusionに書かれてるね
643デフォルトの名無しさん
2019/12/01(日) 13:38:02.71ID:N3Tb7oIA >>640
キミが有名なMIPS君かw
キミが有名なMIPS君かw
644デフォルトの名無しさん
2019/12/01(日) 13:45:41.30ID:npZTl1ra >>640
jcc命令の説明
77 cb JA rel8 D Valid Valid Jump short if above (CF=0 and ZF=0).
73 cb JAE rel8 D Valid Valid Jump short if above or equal (CF=0).
キャリーフラグは使われてるぞ
jcc命令の説明
77 cb JA rel8 D Valid Valid Jump short if above (CF=0 and ZF=0).
73 cb JAE rel8 D Valid Valid Jump short if above or equal (CF=0).
キャリーフラグは使われてるぞ
645デフォルトの名無しさん
2019/12/01(日) 13:47:09.12ID:npZTl1ra ちょっと見難いね
JA Jump short if above (CF=0 and ZF=0).
JAE Jump short if above or equal (CF=0).
JA Jump short if above (CF=0 and ZF=0).
JAE Jump short if above or equal (CF=0).
646デフォルトの名無しさん
2019/12/01(日) 14:13:26.95ID:rpSiZ7Ms647デフォルトの名無しさん
2019/12/01(日) 14:21:48.12ID:npZTl1ra >>646
間にフラグをいじらない他の命令挟むとフュージョン出来ないはずだし、
フュージョンした場合でも、フラグレジスタも一緒に更新するので、フラグを使うと考えていい
演算回路のキャリー信号を使わないということは、まず考えられないよ
間にフラグをいじらない他の命令挟むとフュージョン出来ないはずだし、
フュージョンした場合でも、フラグレジスタも一緒に更新するので、フラグを使うと考えていい
演算回路のキャリー信号を使わないということは、まず考えられないよ
648デフォルトの名無しさん
2019/12/01(日) 14:22:09.47ID:p3Z7Nr0h649デフォルトの名無しさん
2019/12/01(日) 14:23:53.09ID:p3Z7Nr0h RISC-Vは開発経験ないです
650デフォルトの名無しさん
2019/12/01(日) 14:24:03.34ID:rpSiZ7Ms >>647
内部的に1命令のμOPsになるのに何言ってるの?
内部的に1命令のμOPsになるのに何言ってるの?
651デフォルトの名無しさん
2019/12/01(日) 14:31:19.10ID:rpSiZ7Ms CFとZFのみを使うやつはCMPでマクロフィユージョン可能のようだね
652デフォルトの名無しさん
2019/12/01(日) 14:33:05.42ID:npZTl1ra653デフォルトの名無しさん
2019/12/01(日) 14:40:26.09ID:npZTl1ra 確かマクロフュージョンって、実行キューに入るときには別々のμOPsに分解されたはず
整数パイプと分岐ユニット用にね
整数パイプと分岐ユニット用にね
654デフォルトの名無しさん
2019/12/01(日) 15:01:21.03ID:rpSiZ7Ms >>653
また分割しちゃったらマクロフィユージョンで統合した意味なくないか?
>>646のExampleのところにこう書かれてるね
Sandy Bridge microarchitecture enables more arithmetic and logic instructions
to macro-fuse with conditional branches.
In loops where the ALU ports are already congested,
performing one of these macrofusions can relieve the pressure,
as the macro-fused instruction consumes only port 5, instead of an ALU
port plus port 5.
また分割しちゃったらマクロフィユージョンで統合した意味なくないか?
>>646のExampleのところにこう書かれてるね
Sandy Bridge microarchitecture enables more arithmetic and logic instructions
to macro-fuse with conditional branches.
In loops where the ALU ports are already congested,
performing one of these macrofusions can relieve the pressure,
as the macro-fused instruction consumes only port 5, instead of an ALU
port plus port 5.
655デフォルトの名無しさん
2019/12/01(日) 15:30:27.00ID:npZTl1ra >>654
そういや、分解されるのはマイクロフュージョンの方だったか?
ポート5でALUと分岐ユニットが一緒になってるから間違ってたかも、ゴメン
でも、フュージョン出来ない書き方も可能なはずなので、フラグ参照するパターンもあるはずだよ
そういや、分解されるのはマイクロフュージョンの方だったか?
ポート5でALUと分岐ユニットが一緒になってるから間違ってたかも、ゴメン
でも、フュージョン出来ない書き方も可能なはずなので、フラグ参照するパターンもあるはずだよ
656デフォルトの名無しさん
2019/12/01(日) 22:01:05.21ID:N3Tb7oIA >>648
MIPSマシン、RISC-Vマシンなんて手に入らないからMIPSの話はMIPSスレでよくね? ここ初心者板だよ?
ほんとこんなところでスレチのMIPS、RISC-Vニュースコピペしないでくれるかな。
ここム板だよ。荒らしと変わらないよ。興味あるならMIPSスレのほう除くでしょ。
MIPSマシン、RISC-Vマシンなんて手に入らないからMIPSの話はMIPSスレでよくね? ここ初心者板だよ?
ほんとこんなところでスレチのMIPS、RISC-Vニュースコピペしないでくれるかな。
ここム板だよ。荒らしと変わらないよ。興味あるならMIPSスレのほう除くでしょ。
657デフォルトの名無しさん
2019/12/01(日) 22:35:59.05ID:rpSiZ7Ms MIPSならPIC32がMIPS
RISC-Vのマイコンもすぐに手に入るようなった
https://www.switch-science.com/catalog/5707/
https://www.switch-science.com/catalog/5946/
https://www.switch-science.com/catalog/5700/
RISC-Vのマイコンもすぐに手に入るようなった
https://www.switch-science.com/catalog/5707/
https://www.switch-science.com/catalog/5946/
https://www.switch-science.com/catalog/5700/
658デフォルトの名無しさん
2019/12/01(日) 22:42:54.44ID:N3Tb7oIA MIPS君って人の話聞かない人なんだな。
659デフォルトの名無しさん
2019/12/01(日) 22:47:20.58ID:rpSiZ7Ms RISC-VのSBC
HiFive1
http://select.marutsu.co.jp/list/detail.php?id=351
MIPSのSBCもあることはあるぞ
Imagination Technologies Creator Ci40 IoT 開発 ボード
https://jp.rs-online.com/web/p/processor-microcontroller-development-kits/1253306/
Imagination Technologies Creator Ci20 Linux/Android 開発 ボード
https://jp.rs-online.com/web/p/processor-microcontroller-development-kits/1253305/
HiFive1
http://select.marutsu.co.jp/list/detail.php?id=351
MIPSのSBCもあることはあるぞ
Imagination Technologies Creator Ci40 IoT 開発 ボード
https://jp.rs-online.com/web/p/processor-microcontroller-development-kits/1253306/
Imagination Technologies Creator Ci20 Linux/Android 開発 ボード
https://jp.rs-online.com/web/p/processor-microcontroller-development-kits/1253305/
660デフォルトの名無しさん
2019/12/01(日) 22:54:42.00ID:rpSiZ7Ms RISC-Vが手に入るようになったからトランジスタ技術2019年11月号や
インターフェースの2019年12月号で特集やってるわけだが
インターフェースの2019年12月号で特集やってるわけだが
661デフォルトの名無しさん
2019/12/01(日) 23:20:53.64ID:rpSiZ7Ms662デフォルトの名無しさん
2019/12/01(日) 23:26:12.86ID:npZTl1ra MIPS君?って、
>フラグはアウトオブオーダーの妨げになるし
>並列化も出来ないから
って主張が完全崩壊して、当分は現れないんじゃないかな…
アウトオブオーダーの知識も色々とおかしくて、あれで最適化の講釈する度胸はないだろ
>フラグはアウトオブオーダーの妨げになるし
>並列化も出来ないから
って主張が完全崩壊して、当分は現れないんじゃないかな…
アウトオブオーダーの知識も色々とおかしくて、あれで最適化の講釈する度胸はないだろ
663デフォルトの名無しさん
2019/12/01(日) 23:36:04.53ID:rpSiZ7Ms 複数の人間の書き込みを同一人物視する人は頭おかしい
664デフォルトの名無しさん
2019/12/01(日) 23:38:09.37ID:Tj+WH/IS Cortex-M7やRXv3と競合するRISC-Vコア搭載のASICはよこい
665デフォルトの名無しさん
2019/12/02(月) 00:11:51.31ID:RIgVO6ZZ >>657
とりあえず買ってみる
とりあえず買ってみる
666デフォルトの名無しさん
2019/12/02(月) 19:22:50.55ID:kmSxls5X AVX512に慣れると、
他のコアがチープに見える
特に32bit〜64bitの中途半端なヤツが
京の次のヤツのARMってSIMD何ビットだっけ?
ちょっと遊んでみたい
他のコアがチープに見える
特に32bit〜64bitの中途半端なヤツが
京の次のヤツのARMってSIMD何ビットだっけ?
ちょっと遊んでみたい
667デフォルトの名無しさん
2019/12/02(月) 19:24:16.67ID:kmSxls5X PICみたいな超チープなやつは
それはそれで楽しいんだけど
それはそれで楽しいんだけど
668デフォルトの名無しさん
2019/12/03(火) 10:01:22.58ID:kL4hKD0u チープというか変態すぎる。
669デフォルトの名無しさん
2019/12/03(火) 11:32:29.72ID:g2sdmHcp チープなやつは大体どれも変態だよ
C言語で記述不可能なのもあるから
PICは変態な中でもまだマシな方
C言語で記述不可能なのもあるから
PICは変態な中でもまだマシな方
670デフォルトの名無しさん
2019/12/13(金) 00:51:18.32ID:7tDteGkj PICは命令数が少ないから大好き
アセンブラは慣れれば問題ない
アセンブラは慣れれば問題ない
671デフォルトの名無しさん
2019/12/13(金) 18:29:36.28ID:1MRTxPI4 GOTOで発作が起きます
672デフォルトの名無しさん
2019/12/13(金) 19:12:30.36ID:QuzLYYNu gotoアレルギー多いよな
673デフォルトの名無しさん
2019/12/13(金) 20:44:16.76ID:tYi2uLeR JP じゃないの
674デフォルトの名無しさん
2019/12/14(土) 02:42:04.15ID:er8xklWG 日本では特に間違って伝わってるからなぁ
想像するのがC言語やスクリーンエディタ機能組み込まれてた頃のBASICのGOTOっていう
想像するのがC言語やスクリーンエディタ機能組み込まれてた頃のBASICのGOTOっていう
675デフォルトの名無しさん
2019/12/14(土) 07:46:40.45ID:6lStbnNy 古臭くて役にも立たない話をするのが大好きで、LARGEADDRESSAWAREやキャリーフラグで
大爆死した誰かさんがしれっと戻って来てるのか?
大爆死した誰かさんがしれっと戻って来てるのか?
676デフォルトの名無しさん
2019/12/14(土) 12:04:43.11ID:teIen0U1 GOTOがというより抽象化に関する教育の不足が問題なんじゃ
昨今のプログラミング教育も本質が見えているようには見えない
昨今のプログラミング教育も本質が見えているようには見えない
677デフォルトの名無しさん
2019/12/14(土) 12:07:38.82ID:2PNj6NH4 歪んだ教育のせいで
ループ内で意地でも
continue, break, goto
を使わない人がいる
その為、
無駄な変数を使ったり
ループ条件が複雑になったり
本末転倒
ループ内で意地でも
continue, break, goto
を使わない人がいる
その為、
無駄な変数を使ったり
ループ条件が複雑になったり
本末転倒
678デフォルトの名無しさん
2019/12/14(土) 13:25:49.98ID:TlZt0bii breakにラベル指定出来なかったのはCの設計ミスやろ
679デフォルトの名無しさん
2019/12/14(土) 13:34:05.64ID:JwYnIOEa 多重ループはgotoで抜ける
って事だろうけどね
gotoはラベル名を考えるのが面倒
break 2;
で2段階breakが出来ると良い
って事だろうけどね
gotoはラベル名を考えるのが面倒
break 2;
で2段階breakが出来ると良い
680デフォルトの名無しさん
2019/12/14(土) 13:39:05.39ID:qH7KRmrQ >>679
N88-BASICのような時代は、行番号があったからラベル名を考える必要が
なく楽だった。MASMの場合は、プロシージャローカルのラベル名が
使えたので、lab1:, lab2: のようにしておくと楽だった。
Cの場合、見た目的に「ラベルが浮く」現象が起きるのも問題。
N88-BASICのような時代は、行番号があったからラベル名を考える必要が
なく楽だった。MASMの場合は、プロシージャローカルのラベル名が
使えたので、lab1:, lab2: のようにしておくと楽だった。
Cの場合、見た目的に「ラベルが浮く」現象が起きるのも問題。
681デフォルトの名無しさん
2019/12/14(土) 13:44:49.72ID:qH7KRmrQ BASICの場合、
1000 xxx
1010 if xxx > xxx then 1200
1020 xxx
1030 goto 1300
1200 xxx
のように書けて至って楽だったし、見た目も綺麗に書けた。
アセンブラの場合も
xxx proc near
mov yyy,zzz
lab1:
call aaa
lab2:
dec ecx
jnz bbb
xxx endp
のように命令の前には tab(0x09) 付けされ、ラベルと区別が付き易いのでとても
綺麗に書けた。ところがCの場合は、ラベルと命令の見た目のバランスが悪いので
問題となった。構造上の汚さよりもその問題の方が大きい。
1000 xxx
1010 if xxx > xxx then 1200
1020 xxx
1030 goto 1300
1200 xxx
のように書けて至って楽だったし、見た目も綺麗に書けた。
アセンブラの場合も
xxx proc near
mov yyy,zzz
lab1:
call aaa
lab2:
dec ecx
jnz bbb
xxx endp
のように命令の前には tab(0x09) 付けされ、ラベルと区別が付き易いのでとても
綺麗に書けた。ところがCの場合は、ラベルと命令の見た目のバランスが悪いので
問題となった。構造上の汚さよりもその問題の方が大きい。
682デフォルトの名無しさん
2019/12/14(土) 13:48:16.80ID:JwYnIOEa683デフォルトの名無しさん
2019/12/14(土) 13:50:15.98ID:JwYnIOEa ラベルはインデントを1個左にずらす
case文と同じように
case文と同じように
684デフォルトの名無しさん
2019/12/14(土) 16:23:54.51ID:qH7KRmrQ >>683
こんな感じですか?
{
{
ラベル名1:
if ( xxx < yyy ) {
普通の文1;
ラベル名2:
普通の文2;
}
}
}
こんな感じですか?
{
{
ラベル名1:
if ( xxx < yyy ) {
普通の文1;
ラベル名2:
普通の文2;
}
}
}
685デフォルトの名無しさん
2019/12/14(土) 16:57:20.57ID:er8xklWG caseって用途は限定されてるけど、飛び先ラベルそのものよな?
686デフォルトの名無しさん
2019/12/14(土) 17:00:28.16ID:JwYnIOEa >>684
そうそう
そうそう
687デフォルトの名無しさん
2019/12/14(土) 17:27:51.24ID:IqAY6EvB 実装が楽なのだろうが条件スキップ命令が嫌い。
688デフォルトの名無しさん
2019/12/14(土) 22:37:51.56ID:JwYnIOEa 好きとか嫌いとかどうでも良い
689デフォルトの名無しさん
2019/12/14(土) 22:59:07.71ID:uFdEOStu 最初に言い出したのは誰なのかしら
690デフォルトの名無しさん
2019/12/15(日) 01:17:17.22ID:f1vDrgvb PICのアセンブラは非人間的で嫌われている
691デフォルトの名無しさん
2019/12/15(日) 11:22:32.97ID:ymerGKQi アセンブラは元々CPUに寄せてるのが普通で、人間に合わせるなんてこと考えてません。
人間がわかりやすいようにしたければマクロで補うなり、プリプロセッサ作るなどして工夫すればいいんですよ。
人間がわかりやすいようにしたければマクロで補うなり、プリプロセッサ作るなどして工夫すればいいんですよ。
692デフォルトの名無しさん
2019/12/15(日) 11:26:35.35ID:mSzJWPy5 PICくらいで非人道的とか
もっと変態CPUはいくらでもあるってのに
もっと変態CPUはいくらでもあるってのに
693デフォルトの名無しさん
2019/12/15(日) 13:07:08.62ID:o9m7qUoD ハーバードだろ
694デフォルトの名無しさん
2019/12/15(日) 13:31:23.47ID:ymerGKQi >>692
でもね、プロセッサ変わる度に覚え直すのは面倒だしつらいだろ。
面倒なものや難しいものをそのまま力業で押し通そうとするのはやっぱり頭悪いやり方。
賢い人なら、もっと頭使って少しでも使いやすく、わかりやすく変えていくもんだと思うんだよね。
でもね、プロセッサ変わる度に覚え直すのは面倒だしつらいだろ。
面倒なものや難しいものをそのまま力業で押し通そうとするのはやっぱり頭悪いやり方。
賢い人なら、もっと頭使って少しでも使いやすく、わかりやすく変えていくもんだと思うんだよね。
695デフォルトの名無しさん
2019/12/15(日) 17:23:58.99ID:5kgRNS4L RXのアセンブラは判りやすいと思う
696デフォルトの名無しさん
2019/12/15(日) 17:38:53.02ID:5sPbacoo >>694
C言語
C言語
697デフォルトの名無しさん
2019/12/15(日) 19:26:43.84ID:ymerGKQi >>696
Cが対応しているプロセッサならそれ使えばいいけど、同じ処理をアセンブラで書くのとCで書いたのでは実行ファイルのサイズが大きく違う。
Cは余計なランタイムルーチンがリンクされて無駄に太る。Cで書いてもアセンブラで書くのとほとんど同じサイズになる処理系があればその方が良い。
そして、なければ作るしかない。覚えにくいニーモニックを頑張って覚えるくらいなら、そういう処理系を作ることに労力を使ったほうがいいんじゃないかな。
Cが対応しているプロセッサならそれ使えばいいけど、同じ処理をアセンブラで書くのとCで書いたのでは実行ファイルのサイズが大きく違う。
Cは余計なランタイムルーチンがリンクされて無駄に太る。Cで書いてもアセンブラで書くのとほとんど同じサイズになる処理系があればその方が良い。
そして、なければ作るしかない。覚えにくいニーモニックを頑張って覚えるくらいなら、そういう処理系を作ることに労力を使ったほうがいいんじゃないかな。
698デフォルトの名無しさん
2019/12/15(日) 19:42:57.22ID:5kgRNS4L 今時マイコンですら結構な容量のフラッシュROMを積んでいるし
高級言語に由来するフットプリント増が問題になるケースは少ないと思うが
高いリアルタイム性が要求されたり重い処理をするケースはアセンブラで書く場合がある
高級言語に由来するフットプリント増が問題になるケースは少ないと思うが
高いリアルタイム性が要求されたり重い処理をするケースはアセンブラで書く場合がある
699デフォルトの名無しさん
2019/12/15(日) 20:20:04.05ID:5sPbacoo >>697
需要がないプロセッサは作らない
それだけ
変態アーキテクチャは理由があってそうなってる訳だし
普通のCPUならC/C++で使いやすいように整備されてる
Cランタイムサイズが問題になるCPUだと
ランタイムも小さく出来るのが普通
(printf、malloc を使わないなど)
需要がないプロセッサは作らない
それだけ
変態アーキテクチャは理由があってそうなってる訳だし
普通のCPUならC/C++で使いやすいように整備されてる
Cランタイムサイズが問題になるCPUだと
ランタイムも小さく出来るのが普通
(printf、malloc を使わないなど)
700デフォルトの名無しさん
2019/12/15(日) 20:21:43.99ID:jswNPg7r 8bitCPUにFlashROM 32KBにRAMが1KB、広すぎて天国のようだ
701デフォルトの名無しさん
2019/12/15(日) 20:22:30.32ID:5sPbacoo >>700
だよね
だよね
702デフォルトの名無しさん
2019/12/15(日) 20:28:26.55ID:5sPbacoo 小規模DSPは比較的アセンブラを良く使う
703デフォルトの名無しさん
2019/12/18(水) 03:42:06.43ID:mwLPhsOw ラーメンには豚のセアブラをよく使う
704デフォルトの名無しさん
2020/01/14(火) 15:59:36.64ID:uFo9dhko 68000君は居ないようだな。残念だ
C言語も神が作ったのではない、breakやcontinueがどこに飛ぶのか分からん時はある。
入門書を信じ込んだ狂信者、原理主義者のような、痛い目に会ってない素人は結構いる。
C言語も神が作ったのではない、breakやcontinueがどこに飛ぶのか分からん時はある。
入門書を信じ込んだ狂信者、原理主義者のような、痛い目に会ってない素人は結構いる。
705デフォルトの名無しさん
2020/01/14(火) 19:13:53.43ID:VTSZmZmV >>704
> breakやcontinueがどこに飛ぶのか分からん時はある。
そんな経験はないなあ。普通はCの仕様通りに動く。
Cの仕様通りに動かないとしたらそのCコンパイラのバグだと思いますよ。
もし本当にわけがわからない動作をしたときはテストプログラムを書いてどう動くか調べたり
アセンブラソース出力して見てみればいい。
> breakやcontinueがどこに飛ぶのか分からん時はある。
そんな経験はないなあ。普通はCの仕様通りに動く。
Cの仕様通りに動かないとしたらそのCコンパイラのバグだと思いますよ。
もし本当にわけがわからない動作をしたときはテストプログラムを書いてどう動くか調べたり
アセンブラソース出力して見てみればいい。
706デフォルトの名無しさん
2020/01/15(水) 10:28:18.25ID:NnMYiXUN ソースを追う気がなくなるからわからなくなるって意味だろ
707デフォルトの名無しさん
2020/01/15(水) 12:54:18.67ID:mdjDjCL2 素朴な疑問なんだが逆アセンブラのラベルってどうやって生成されるの?
レジスタ間接ジャンプのジャンプ先アドレスなんて実行してみないと判らないような・・・
レジスタ間接ジャンプのジャンプ先アドレスなんて実行してみないと判らないような・・・
708デフォルトの名無しさん
2020/01/15(水) 22:23:13.85ID:NnMYiXUN PEヘッダ内にあるImage baseとかじゃね win32の場合だけど
709デフォルトの名無しさん
2020/01/16(木) 05:34:03.43ID:I1VMveuP >>705
>そんな経験はないなあ。普通はCの仕様通りに動く。
多重ループ脱出やifやなんやらのネストでどこに行くか分からなくなる事は無かったんか
Cの経験浅い人は、そういうことが分からないんだろうな。
>そんな経験はないなあ。普通はCの仕様通りに動く。
多重ループ脱出やifやなんやらのネストでどこに行くか分からなくなる事は無かったんか
Cの経験浅い人は、そういうことが分からないんだろうな。
710デフォルトの名無しさん
2020/01/16(木) 07:53:03.25ID:oL142J5t インデントがぐちゃぐちゃなパターンは昔はよく見た。viのせいだろうな。
711デフォルトの名無しさん
2020/01/16(木) 08:04:26.22ID:TEF1jMG0 今も見る
712デフォルトの名無しさん
2020/01/16(木) 23:36:50.30ID:GgmseacB >>709
複雑なものを複雑なままコードにするからそうなる。
多重ループと言ってもせいぜい2重か3重だし、それ以上深いループになるようなコードだったら
そもそも考え方が悪いからシンプルになるように書き直す。中身をサブルーチンに追い出して、
ループ構造と脱出が一目でわかるようにしても良い。
ifのネストも同様に、細部の条件を洗い出してパラメータを変えて呼び出すだけで動くようにする。
そうすればif文を見なくていいしそれぞれ1行で呼び出せる。
とにかくできるだけ構造がシンプルでわかりやすくなるように工夫することだよ。
複雑なものを複雑なままコードにするからそうなる。
多重ループと言ってもせいぜい2重か3重だし、それ以上深いループになるようなコードだったら
そもそも考え方が悪いからシンプルになるように書き直す。中身をサブルーチンに追い出して、
ループ構造と脱出が一目でわかるようにしても良い。
ifのネストも同様に、細部の条件を洗い出してパラメータを変えて呼び出すだけで動くようにする。
そうすればif文を見なくていいしそれぞれ1行で呼び出せる。
とにかくできるだけ構造がシンプルでわかりやすくなるように工夫することだよ。
713デフォルトの名無しさん
2020/01/18(土) 09:17:15.53ID:bQ1xI4/b714デフォルトの名無しさん
2020/02/13(木) 22:12:36.79ID:z5jUasH9 最近パスタ食べてないな
715デフォルトの名無しさん
2020/03/04(水) 14:16:54.94ID:b3xLS7HK 究極の変態ってどんな感じなんだろうな
パズル的で面白そうだが…
パズル的で面白そうだが…
716デフォルトの名無しさん
2020/05/14(木) 17:51:17.70ID:f1vNNG/3 まったくの初心者なのですが、アセンブリ言語を理解できるようになりたいです。
入門サイトなどを探しても自分が探しているCPUを取り扱っている物は見つかりませんでした。
まだCPUの仕組みもよく理解していないような状態なので、種類に拘らずそのような入門サイトなどで勉強した方がいいのでしょうか。
一通り学習を終えた後、別のCPUの言語でもすぐ対応できますか?
iosアプリのリバースエンジニアリング をしてみたいと思っているのでarm64のコードを理解できるようになりたいです。(用語などの使い方が間違っていたらすみません。)
入門サイトなどを探しても自分が探しているCPUを取り扱っている物は見つかりませんでした。
まだCPUの仕組みもよく理解していないような状態なので、種類に拘らずそのような入門サイトなどで勉強した方がいいのでしょうか。
一通り学習を終えた後、別のCPUの言語でもすぐ対応できますか?
iosアプリのリバースエンジニアリング をしてみたいと思っているのでarm64のコードを理解できるようになりたいです。(用語などの使い方が間違っていたらすみません。)
717デフォルトの名無しさん
2020/05/14(木) 17:59:48.21ID:xR/PZA9p マルチ死ね
718デフォルトの名無しさん
2020/05/14(木) 19:21:25.82ID:FSEZeoAj 情報処理資格の教科書から、始めた方がよい。
CASL 2 という仮想アセンブラもある
仮想アセンブラとは、各メーカーごとの実際のアセンブラではなくて、抽象的なもの
仮想アセンブラでは、LLVM が最も有名
CASL 2 という仮想アセンブラもある
仮想アセンブラとは、各メーカーごとの実際のアセンブラではなくて、抽象的なもの
仮想アセンブラでは、LLVM が最も有名
719デフォルトの名無しさん
2020/05/15(金) 10:21:28.00ID:QqRlTuRs 動機を当ててやるか。ゲームを改造して無双したいのだろう。
だがそんなの対策済みで無駄なことだ。
だがそんなの対策済みで無駄なことだ。
720デフォルトの名無しさん
2020/06/17(水) 20:16:42.08ID:mLHHLomt 実プロセッサのアセンブラを学ぶのに仮想アセンブラって役立つか?
LLVMなんてレジスタ数無制限だしスタック無しでも処理を書けるだろ
実際のプロセッサでそれは現実的ではないしスタック操作はボトルネックにもなっている
LLVMなんてレジスタ数無制限だしスタック無しでも処理を書けるだろ
実際のプロセッサでそれは現実的ではないしスタック操作はボトルネックにもなっている
721デフォルトの名無しさん
2020/06/18(木) 06:16:16.86ID:WpoR9KQA ARM64のアセンブラだとこんなサイトあるよ
http://www.mztn.org/dragon/arm6400idx.html
http://www.mztn.org/dragon/arm6400idx.html
722デフォルトの名無しさん
2020/06/21(日) 16:12:29.75ID:rRP2z2l8 MPUそのものは仮想でもエミュがあってそこそこ実用になるなら良いんじゃない?
723デフォルトの名無しさん
2020/06/21(日) 16:13:57.40ID:pgbZYzU2 比べるのもアレだけど
極端な話 BrainF*ck も仮想みたいなもんだろ
極端な話 BrainF*ck も仮想みたいなもんだろ
724デフォルトの名無しさん
2020/06/30(火) 20:45:59.73ID:2de2B/rP コンパイラにアセンブラ出力させてみた結果
8bitのアセンブラが簡単なんて嘘
Cソース
https://pastebin.com/bWfLhn8Y
8bit MSX-C Ver1.1 アセンブラ出力
https://pastebin.com/Bzt3fFaX
16bit Turbo-C Ver1.5 アセンブラ出力
https://pastebin.com/y82ifpxs
64bit Ubuntu 18.04 x86_64 gcc-7.4.0 アセンブラ出力
https://pastebin.com/PTuEv5uL
64bit Ubuntu 20.04 ARM64 gcc-9.3.0 アセンブラ出力
https://pastebin.com/9N4eKWeg
8bitのアセンブラが簡単なんて嘘
Cソース
https://pastebin.com/bWfLhn8Y
8bit MSX-C Ver1.1 アセンブラ出力
https://pastebin.com/Bzt3fFaX
16bit Turbo-C Ver1.5 アセンブラ出力
https://pastebin.com/y82ifpxs
64bit Ubuntu 18.04 x86_64 gcc-7.4.0 アセンブラ出力
https://pastebin.com/PTuEv5uL
64bit Ubuntu 20.04 ARM64 gcc-9.3.0 アセンブラ出力
https://pastebin.com/9N4eKWeg
725デフォルトの名無しさん
2020/06/30(火) 20:50:56.99ID:2de2B/rP ちなみにgccでは
int func01() __attribute__((noinline,noclone));
とやってインライン展開を抑制してます
int func01() __attribute__((noinline,noclone));
とやってインライン展開を抑制してます
726デフォルトの名無しさん
2020/06/30(火) 21:02:04.38ID:e6PapWOV 8bitの方がソフト規模が小さいから簡単
727デフォルトの名無しさん
2020/06/30(火) 21:05:11.63ID:dU7zENbL728デフォルトの名無しさん
2020/06/30(火) 21:11:37.45ID:e6PapWOV 単純な命令しかなくて命令数も圧倒的に少ない8bit
複雑な命令がたくさんあって命令数も1000を越える64bit
複雑な命令がたくさんあって命令数も1000を越える64bit
729デフォルトの名無しさん
2020/07/01(水) 04:08:07.95ID:g4YauoQu コンパイラの変換が下手
730デフォルトの名無しさん
2020/07/01(水) 04:09:06.24ID:GZMydJ4F731デフォルトの名無しさん
2020/07/01(水) 06:53:53.79ID:8lUxucUi 溢れても規模が小さいから簡単
732デフォルトの名無しさん
2020/07/01(水) 10:54:24.39ID:dk2qwU4W 簡単さだったら新しいCISCに分があるんじゃね
ttps://uploader.purinka.work/src/17167.png
R0はスタックポインタ。呼び出し規約の都合上引数の一部が
スタックに積まれている以外はamd64と同じ感じか
同じ8bitでも8051とAVRじゃ大分違うと思う
ttps://uploader.purinka.work/src/17167.png
R0はスタックポインタ。呼び出し規約の都合上引数の一部が
スタックに積まれている以外はamd64と同じ感じか
同じ8bitでも8051とAVRじゃ大分違うと思う
733デフォルトの名無しさん
2020/07/01(水) 11:12:01.44ID:BWQBxkNi 命令を覚える命令を使うのが簡単か
同じ機能を実現するのが簡単か
で結果が180度違う
同じ機能を実現するのが簡単か
で結果が180度違う
734デフォルトの名無しさん
2020/07/01(水) 11:14:42.34ID:BWQBxkNi 8bitCPUのソフトエンジニア
64bitCPUのソフトエンジニア
どちらがより多くの知識や経験が必要か
一般的には64bitの方が必要
64bitCPUのソフトエンジニア
どちらがより多くの知識や経験が必要か
一般的には64bitの方が必要
735デフォルトの名無しさん
2020/07/01(水) 13:04:54.17ID:hOLEVQcG 本当はわかっていて、ちょっと言い合いたいだけだろうな
736デフォルトの名無しさん
2020/07/01(水) 19:06:42.33ID:rX+J+WIV >>731
規模が小さいなら64bitでも簡単。Intel系なら命令も上位互換だからほぼ同じ命令が使える。
規模が小さいなら64bitでも簡単。Intel系なら命令も上位互換だからほぼ同じ命令が使える。
737デフォルトの名無しさん
2020/07/01(水) 19:48:13.47ID:8lUxucUi 64bitは通常8bitよりソフト規模が大きい
738デフォルトの名無しさん
2020/07/01(水) 21:20:19.29ID:mNMvI8FZ IA-32よりAMD64の方が簡単なんじゃないか説(汎用レジスタの本数的に)
739デフォルトの名無しさん
2020/07/02(木) 08:31:24.65ID:RyBCtyYa 8bitが簡単と言われるのは命令の数が限られてるのと、簡単なことしかしないから
64bitでもよく使われる限られた命令だけ使って、8bitと同じことをやれば
8bitよりも簡単
実際は周辺や割り込みコントローラなんかもリッチになるので大変だけどね
Arduinoみたいにそのあたりを意識しないなら64bitの方が8bitよりも簡単
64bitでもよく使われる限られた命令だけ使って、8bitと同じことをやれば
8bitよりも簡単
実際は周辺や割り込みコントローラなんかもリッチになるので大変だけどね
Arduinoみたいにそのあたりを意識しないなら64bitの方が8bitよりも簡単
740デフォルトの名無しさん
2020/07/02(木) 10:37:27.14ID:KAImZ3Ow 結局どっちも簡単ってことだな
741デフォルトの名無しさん
2020/07/02(木) 13:41:50.00ID:ueeOma1J742デフォルトの名無しさん
2020/07/02(木) 19:26:50.19ID:1S4E8SKc それ言い出したら
そもそも普通はアセンブラなんか使わん
そもそも普通はアセンブラなんか使わん
743デフォルトの名無しさん
2020/07/02(木) 19:30:02.70ID:1S4E8SKc アセンブラでしか書けない特殊処理(特殊命令、特殊レジスタへのアクセスなど)
速度やリソースのチューニング
趣味
速度やリソースのチューニング
趣味
744デフォルトの名無しさん
2020/07/02(木) 20:08:46.86ID:L2HGsVdw まあ趣味だな。Cで書けない処理をアセンブラで書けたら「やった」て気になるしな。
745デフォルトの名無しさん
2020/07/02(木) 20:21:06.52ID:1S4E8SKc それはアセンブラでしか書けない特殊処理ではなくて?
746デフォルトの名無しさん
2020/07/02(木) 20:31:36.38ID:L2HGsVdw 趣味だからどういう処理でも自分が満足できればそれでいいんじゃね?
簡単な処理から始めてだんだん難しい処理に挑戦するのも面白いし
簡単な処理から始めてだんだん難しい処理に挑戦するのも面白いし
747デフォルトの名無しさん
2020/07/02(木) 20:51:16.74ID:dBIHsFi5 組み込みで非標準的な実装をしたい場合はアセンブラを使ったりするな
仮にアセンブラの本を書くとして、その題材になにを選ぶか、アセンブラだからこそできる!というナイスな題材がほとんど思いつかないのです…
749デフォルトの名無しさん
2020/07/02(木) 22:24:08.15ID:L2HGsVdw 思いつかないってことは、本当にやりたいと思ってないってことだろうな。
たとえば部屋で飼ってる猫の様子を出先から監視したいと思ったらArduinoとカメラユニットを組み合わせて
スマホから見られる制御ソフトを作るだろう。
たとえば部屋で飼ってる猫の様子を出先から監視したいと思ったらArduinoとカメラユニットを組み合わせて
スマホから見られる制御ソフトを作るだろう。
>>749
それはアセンブラだからこそできる、という題材ですか?
それはアセンブラだからこそできる、という題材ですか?
751デフォルトの名無しさん
2020/07/02(木) 23:32:35.76ID:1S4E8SKc スタートアップコードの記述
OS作成
くらいじゃね?
OS作成
くらいじゃね?
752デフォルトの名無しさん
2020/07/02(木) 23:34:12.29ID:1S4E8SKc パフォーマンス系なら
DSP制御とか
リアルタイム系の重い処理とか
DSP制御とか
リアルタイム系の重い処理とか
753デフォルトの名無しさん
2020/07/02(木) 23:36:24.16ID:1S4E8SKc >>749
アセンブラが適さない典型
アセンブラが適さない典型
754デフォルトの名無しさん
2020/07/02(木) 23:38:56.48ID:dBIHsFi5 ペリフェラルAとペリフェラルBを同期させて動かしたいなんて場合はアセンブラの使用を検討する
755デフォルトの名無しさん
2020/07/02(木) 23:40:30.23ID:1S4E8SKc えらい抽象的だな
タイミングにシビアなのはコンパイラに依存しないようにアセンブラで書くってのはある
もちろんシビアな部分だけ
タイミングにシビアなのはコンパイラに依存しないようにアセンブラで書くってのはある
もちろんシビアな部分だけ
756デフォルトの名無しさん
2020/07/02(木) 23:42:01.52ID:1S4E8SKc >>747
これも抽象的で何の実装だかさっぱりわからん
これも抽象的で何の実装だかさっぱりわからん
757デフォルトの名無しさん
2020/07/03(金) 04:39:01.80ID:/VSGTLiK >>748
やっぱり、SIMD命令とか組み込みだとDSP命令を使いたい時とかじゃないの?
やっぱり、SIMD命令とか組み込みだとDSP命令を使いたい時とかじゃないの?
758デフォルトの名無しさん
2020/07/03(金) 07:56:44.00ID:jbweNl0h 最近ではSIMDやDSP命令はCの文法で記述出来るのが普通
もちろんガチガチのチューニングはアセンブラが一番だから
結局チューニングという範疇
もちろんガチガチのチューニングはアセンブラが一番だから
結局チューニングという範疇
759デフォルトの名無しさん
2020/07/03(金) 17:33:03.39ID:Rc6pK0Eu >>750
俺は「アセンブラだからこそ」という制限など付けていない。そういう制限はあんたが勝手に付けたものだ。
作りたいものを作る。それが趣味だ。
違うと思うなら自分で考えてアセンブラだからこそというものを作ればいい。
俺は「アセンブラだからこそ」という制限など付けていない。そういう制限はあんたが勝手に付けたものだ。
作りたいものを作る。それが趣味だ。
違うと思うなら自分で考えてアセンブラだからこそというものを作ればいい。
760デフォルトの名無しさん
2020/07/03(金) 17:34:28.08ID:Rc6pK0Eu761デフォルトの名無しさん
2020/07/03(金) 18:57:27.44ID:C0RVqI6W 趣味ならアセンブラを使う理由なんて何でも良い
でもどうせならアセンブラを使うことでメリットが何かしら得られる方が良い
そのメリットは大きい方が良い
と思うのは普通かと
でもどうせならアセンブラを使うことでメリットが何かしら得られる方が良い
そのメリットは大きい方が良い
と思うのは普通かと
762デフォルトの名無しさん
2020/07/03(金) 19:34:45.09ID:Rc6pK0Eu >>761
趣味は一般的なメリットなんか考えてたらできない。
鉄ヲタなんか、自分で電車運転したいためだけにパソコンのシミュレータを自作してる。
それも20年もかけて作って値段は0。タダで配ってる。金銭的なメリットはゼロだ。
窓から見える信号機や駅のデータも手間暇かけて現地に行ってパソコンのデータに変換してる。
運転席の計器類やすれ違う電車のモデルやデザイン、色まで正確に再現してる。
とてもこれだけの手間に見合うメリットがあるとは思えない。
でもこれだけの無駄をしてもやりたいのが趣味なんだよ。
鉄ヲタがアセンブラを使うとしたら、電車が動くスピードが少し遅く感じるから本物と同じくらい反応を早くしたいと
思ったらすぐ使うだろう。とにかくやりたいからやる。それ以外のことは考えないのが趣味だよ。
趣味は一般的なメリットなんか考えてたらできない。
鉄ヲタなんか、自分で電車運転したいためだけにパソコンのシミュレータを自作してる。
それも20年もかけて作って値段は0。タダで配ってる。金銭的なメリットはゼロだ。
窓から見える信号機や駅のデータも手間暇かけて現地に行ってパソコンのデータに変換してる。
運転席の計器類やすれ違う電車のモデルやデザイン、色まで正確に再現してる。
とてもこれだけの手間に見合うメリットがあるとは思えない。
でもこれだけの無駄をしてもやりたいのが趣味なんだよ。
鉄ヲタがアセンブラを使うとしたら、電車が動くスピードが少し遅く感じるから本物と同じくらい反応を早くしたいと
思ったらすぐ使うだろう。とにかくやりたいからやる。それ以外のことは考えないのが趣味だよ。
763デフォルトの名無しさん
2020/07/03(金) 19:49:18.27ID:v8523RMt 鉄オタきも
って言ってほしい感じ?
って言ってほしい感じ?
764デフォルトの名無しさん
2020/07/03(金) 19:52:48.87ID:v8523RMt 再現性がメリット
ならそれでいいじゃん
アセンブラを使うことで
高速化とか
リソースの節約とか
それもメリット
高速化もせず
リソースも変わらず
質が落ちる
だと何のためのアセンブラ?
ならそれでいいじゃん
アセンブラを使うことで
高速化とか
リソースの節約とか
それもメリット
高速化もせず
リソースも変わらず
質が落ちる
だと何のためのアセンブラ?
765デフォルトの名無しさん
2020/07/03(金) 21:30:22.45ID:Rc6pK0Eu >>763
BSDヲタきもって言ってやろうか?
BSDヲタきもって言ってやろうか?
766デフォルトの名無しさん
2020/07/04(土) 00:06:32.98ID:KYM6hePT http://www.littlebsd.com/
https://twitter.com/little_bsd
https://twitter.com/5chan_nel (5ch newer account)
https://twitter.com/little_bsd
https://twitter.com/5chan_nel (5ch newer account)
767デフォルトの名無しさん
2020/07/15(水) 00:32:33.69ID:0MCF5KaT amd64+Linuxでアセンブラを始めたのですが、スタックの状態を勘違いしてのバグや
システムコール時のレジスタの退避し忘れのバグ等に悩まされてます
スタックの利用状況を分かりやすく表示してくれたり、レジスタの状態をチェックしてくれたり
するような、統合開発環境みたいなのはありませんでしょうか
システムコール時のレジスタの退避し忘れのバグ等に悩まされてます
スタックの利用状況を分かりやすく表示してくれたり、レジスタの状態をチェックしてくれたり
するような、統合開発環境みたいなのはありませんでしょうか
768デフォルトの名無しさん
2020/07/15(水) 11:52:01.41ID:Fiuz3Frw 楽したければC使え
769デフォルトの名無しさん
2020/07/15(水) 12:20:50.44ID:cL9c5hZ8 慣れたら悩まなくなる
770デフォルトの名無しさん
2020/07/15(水) 14:03:15.88ID:p6AIoBG7 アセンブラだと自己書き換えコードが出来るぞ
それによる考えられるメリットは様々あり、ここでは書きにくいこともあるw
あと、正確なことは分からんが、OS開発ではアセンブラがしばしば使われていて、特にブートローダーの開発で使われていると聞いたことがあるな
他にはマイコンだとアセンブラの方が開発しやすいこともあったりするのか?知らんけど
俺は、スレッドセーフなプログラミングにはアセンブラの知識が不可欠だと思っているが、これは他者の意見も聞きたいところだな
他にもアセンブラでしか出来ないことはあるのにアセンブラは趣味の為ときたもんだ(怒)
まずコンパイラは確実
エミュレータなんかもそうじゃないのか?知らんけど
それによる考えられるメリットは様々あり、ここでは書きにくいこともあるw
あと、正確なことは分からんが、OS開発ではアセンブラがしばしば使われていて、特にブートローダーの開発で使われていると聞いたことがあるな
他にはマイコンだとアセンブラの方が開発しやすいこともあったりするのか?知らんけど
俺は、スレッドセーフなプログラミングにはアセンブラの知識が不可欠だと思っているが、これは他者の意見も聞きたいところだな
他にもアセンブラでしか出来ないことはあるのにアセンブラは趣味の為ときたもんだ(怒)
まずコンパイラは確実
エミュレータなんかもそうじゃないのか?知らんけど
771デフォルトの名無しさん
2020/07/15(水) 14:24:49.32ID:miBvJk/V >>767
Linuxでは知らんが、VSのデバッガだと、EAXなどのマシンレジスタの内容を常時
表示できる。
スタックに関しては、push、pop を組にすることと、ちゃんと数える習慣を
付けるしかない。
アセンブラは、言語仕様は簡単に思えるかもしれないが、頭脳が必要。
それはちょうど、数学が小学生でも理解できる四則演算だけを組み合わせているだけ
なのに、大部分の人がどこかで難しくなってしまうのと同じようなもの。
Linuxでは知らんが、VSのデバッガだと、EAXなどのマシンレジスタの内容を常時
表示できる。
スタックに関しては、push、pop を組にすることと、ちゃんと数える習慣を
付けるしかない。
アセンブラは、言語仕様は簡単に思えるかもしれないが、頭脳が必要。
それはちょうど、数学が小学生でも理解できる四則演算だけを組み合わせているだけ
なのに、大部分の人がどこかで難しくなってしまうのと同じようなもの。
772デフォルトの名無しさん
2020/07/15(水) 14:29:36.15ID:PuirKKk2 残念な日本語を使う人って多いな
773デフォルトの名無しさん
2020/07/15(水) 14:41:03.67ID:cL9c5hZ8 知能は文章に滲み出る
774デフォルトの名無しさん
2020/07/15(水) 15:59:06.15ID:p6AIoBG7 知能はコードに滲み出る
775デフォルトの名無しさん
2020/07/15(水) 17:04:33.66ID:miBvJk/V 大事なのは、言語ではなく数学。
776デフォルトの名無しさん
2020/07/15(水) 17:58:36.45ID:vzNJtsb7 >>771
おまえが数学を知らないという事は良くわかった
おまえが数学を知らないという事は良くわかった
777デフォルトの名無しさん
2020/07/15(水) 18:23:23.15ID:bZTTdNA2 今時のGUIなデバッガだったらブレーク時にスタックやレジスタの内容を表示できるのは普通じゃね?
個人的にはパイプラインの動作状況を表示してくれるデバッガとか欲しいわ
依存関係に起因するNOP率とか、原因となっている命令の特定とか
個人的にはパイプラインの動作状況を表示してくれるデバッガとか欲しいわ
依存関係に起因するNOP率とか、原因となっている命令の特定とか
778デフォルトの名無しさん
2020/07/15(水) 18:40:28.77ID:miBvJk/V >>776
俺は数学は常時使っているのだが。
俺は数学は常時使っているのだが。
779デフォルトの名無しさん
2020/07/15(水) 18:48:34.73ID:JGqdiMCl >>778
数学を知らないヤツが数学を毎日使うと
数学を知らないヤツが数学を毎日使うと
780デフォルトの名無しさん
2020/07/15(水) 18:51:31.23ID:miBvJk/V781デフォルトの名無しさん
2020/07/15(水) 18:52:38.10ID:JGqdiMCl そう思ってるだけ
782デフォルトの名無しさん
2020/07/15(水) 18:55:17.94ID:miBvJk/V 学生時代に伝説を作ったし、同級生達は知っている。
783デフォルトの名無しさん
2020/07/15(水) 18:57:06.09ID:JGqdiMCl kwsk
784デフォルトの名無しさん
2020/07/15(水) 19:10:04.26ID:p6AIoBG7 アセンブラに詳しい人はスゴい人多いから失礼な態度はとらない方がいいと思う
785デフォルトの名無しさん
2020/07/15(水) 19:16:51.08ID:r/dLTGHk >>767
アセンブラだからと言って人間が1から10まで考えなくてもいいんだよ。
間違いやすい処理はできるだけソフトやツールにさせるように考え方を変えればいい。
スタックの状態が間違いやすいと思うなら、スタックを管理するマクロを組めばいいし、
レジスタ退避を忘れるなら、レジスタ退避するマクロを組んでそれを使えばいい。
アセンブラだからと言って人間が1から10まで考えなくてもいいんだよ。
間違いやすい処理はできるだけソフトやツールにさせるように考え方を変えればいい。
スタックの状態が間違いやすいと思うなら、スタックを管理するマクロを組めばいいし、
レジスタ退避を忘れるなら、レジスタ退避するマクロを組んでそれを使えばいい。
786デフォルトの名無しさん
2020/07/15(水) 20:52:17.63ID:LyK3DjqL その昔8051用のソフトをフルアセンブラで開発したことがある。デバッグは8個のLEDのみ
1500程度のコードだけどスタックや汎用レジスタの操作で苦労した記憶はないな
ペリフェラルの使い方等は大苦戦だったが
>>767は何を作っているのだろうか。IA-32ならともかくAMD64ならレジスタ本数も多いし
複雑なスタック操作をする機会は多くないと思うんだが
1500程度のコードだけどスタックや汎用レジスタの操作で苦労した記憶はないな
ペリフェラルの使い方等は大苦戦だったが
>>767は何を作っているのだろうか。IA-32ならともかくAMD64ならレジスタ本数も多いし
複雑なスタック操作をする機会は多くないと思うんだが
787デフォルトの名無しさん
2020/07/16(木) 03:00:41.32ID:noTJdW03 >>786
お気持ち分かります。
お気持ち分かります。
788デフォルトの名無しさん
2020/07/16(木) 12:38:48.59ID:Bj5j4Y6i 謎の隠しコマンド連発するやつか
789デフォルトの名無しさん
2020/07/16(木) 18:46:15.84ID:Zj8FcZKn790デフォルトの名無しさん
2020/07/16(木) 19:00:00.97ID:RhEyC4tQ >>789
誰と戦ってるの?
誰と戦ってるの?
791デフォルトの名無しさん
2020/07/16(木) 19:02:56.88ID:Zj8FcZKn792デフォルトの名無しさん
2020/07/16(木) 19:43:33.89ID:TL00gXcm スタックにデータ積んでサブルーチンに渡す時がずれやすい
793デフォルトの名無しさん
2020/07/16(木) 19:46:21.84ID:Zj8FcZKn 呼ぶ側がアセンブラ?
何のために?
趣味か?
何のために?
趣味か?
794デフォルトの名無しさん
2020/07/16(木) 20:09:12.31ID:ICgJPJoU 今のアセンブラの需要って
・OS等の低レイヤーの処理をする
・高速化。1クロックでも節約したい
・リアルタイム。nクロック後に○○を実行する必要がある
こんなもんか?
・OS等の低レイヤーの処理をする
・高速化。1クロックでも節約したい
・リアルタイム。nクロック後に○○を実行する必要がある
こんなもんか?
795デフォルトの名無しさん
2020/07/16(木) 20:10:47.57ID:Zj8FcZKn 趣味
796デフォルトの名無しさん
2020/07/16(木) 20:15:52.17ID:Zj8FcZKn リソースを極限までけちる (ROM/RAM)
797デフォルトの名無しさん
2020/07/16(木) 20:17:12.32ID:Zj8FcZKn 自己書き換えコード
798デフォルトの名無しさん
2020/07/16(木) 22:52:53.48ID:t94iKSIB アセンブラも使ってるって言うとカッコいいから
799デフォルトの名無しさん
2020/07/16(木) 22:54:17.68ID:Zj8FcZKn800デフォルトの名無しさん
2020/07/17(金) 02:55:00.98ID:xni+keKD >>798
この業界では、アセンブラが使える人と使えない人ではやはり使える人の方が尊敬されるよね
この業界では、アセンブラが使える人と使えない人ではやはり使える人の方が尊敬されるよね
801デフォルトの名無しさん
2020/07/17(金) 06:35:47.52ID:CFzyXZw3 そういう歪んだ価値観のせいで
アセンブラじゃなくて良い所までアセンブラにするアホがいる
アセンブラじゃなくて良い所までアセンブラにするアホがいる
802デフォルトの名無しさん
2020/07/17(金) 11:02:40.02ID:hPmghiPz 役に立ってる人は忙しいのでわざわざこんな辺鄙なところに描き込みに来る暇がない
自分も役に立ってない
自分も役に立ってない
803デフォルトの名無しさん
2020/07/17(金) 11:27:34.62ID:vcKdiH1z 仕事が生きがいですの社畜理論?
804デフォルトの名無しさん
2020/07/17(金) 12:58:33.29ID:hPmghiPz805デフォルトの名無しさん
2020/07/17(金) 14:04:20.27ID:xni+keKD >>801
Cが得意だと何でもCで書こうとする。
アセンブラが得意だと何でもアセンブラで書こうとする。
プログラマなら良くあること。
アセンブラがそれほど得意でない人が見たら余計なことと思うんだろうけど。
Cが得意だと何でもCで書こうとする。
アセンブラが得意だと何でもアセンブラで書こうとする。
プログラマなら良くあること。
アセンブラがそれほど得意でない人が見たら余計なことと思うんだろうけど。
806デフォルトの名無しさん
2020/07/17(金) 14:14:01.80ID:BZ2Y/mdT >>805
そういう人はエンジニアとして三流。賃金も三流で良い
そういう人はエンジニアとして三流。賃金も三流で良い
807デフォルトの名無しさん
2020/07/17(金) 14:36:42.77ID:R70AGkgr PICマイコンみたく用途が限られてると、返ってアセンブラの方が短かったりする。
808デフォルトの名無しさん
2020/07/17(金) 15:01:36.87ID:xXsIieN6 PICよりAVR
809デフォルトの名無しさん
2020/07/17(金) 16:45:31.89ID:mOeBhMfJ おいらがマシン語勉強した時(Z80A)ニモニック表見て作ってたね
相対ジャンプなんか手で計算して 今でもコード覚えてるよ LD A = 3E とか LD Bは06とか
アセンブラが手に入った時はなんて便利なんや〜と感動した
当時は子供でまさか仕事でもアセンブラ組むとは思わなかったけどね
相対ジャンプなんか手で計算して 今でもコード覚えてるよ LD A = 3E とか LD Bは06とか
アセンブラが手に入った時はなんて便利なんや〜と感動した
当時は子供でまさか仕事でもアセンブラ組むとは思わなかったけどね
810デフォルトの名無しさん
2020/07/17(金) 17:42:45.57ID:zYg36R0O http://www.yamamo10.jp/yamamoto/comp/Z80/instructions/index.php#LOAD08
A や B にイミディエイト値を入れる場合
00DDD110
DDD はレジスタ番号
B=0, C=1, D=2, E=3, H=4, L=5, A=7
LD B,n は 00000110 (06), n
LD A,n は 00111110 (3E), n
なんで DDD=6 は飛んでるんだっけ
A や B にイミディエイト値を入れる場合
00DDD110
DDD はレジスタ番号
B=0, C=1, D=2, E=3, H=4, L=5, A=7
LD B,n は 00000110 (06), n
LD A,n は 00111110 (3E), n
なんで DDD=6 は飛んでるんだっけ
811デフォルトの名無しさん
2020/07/17(金) 17:45:07.45ID:sm/+SVBD フラグかな
812デフォルトの名無しさん
2020/07/17(金) 17:45:11.86ID:zYg36R0O (HL) が DDD=110 相当にみえなくもないが
命令デコーダーの都合なんだろうな
命令デコーダーの都合なんだろうな
813デフォルトの名無しさん
2020/07/17(金) 21:14:06.39ID:2HBm6uJU >>806
他人の評価などどうでもいい。俺もそんな古くさい見方しかできないあんたを三流と言ってあげよう。
他人の評価などどうでもいい。俺もそんな古くさい見方しかできないあんたを三流と言ってあげよう。
814デフォルトの名無しさん
2020/07/18(土) 13:40:48.90ID:HDs6SbLj >>810
原則的には、DDD=6 は、(HL)に相当している。
原則的には、DDD=6 は、(HL)に相当している。
815デフォルトの名無しさん
2020/07/18(土) 13:46:42.99ID:uRU3MGLx IXとかIYの裏命令の話があるな
816デフォルトの名無しさん
2020/07/18(土) 13:49:01.14ID:HDs6SbLj >>814
昔の事だったし、資料が手元に無いが、原則論として
DDDとかのレジスタ番号の1つとして、(HL)が書いてあり、
それがDDD=6だったと思う。
ただし、原則論なので、全ての命令でDDD=6にすれば必ず合法で、
(HL)になるという意味ではない。
昔の事だったし、資料が手元に無いが、原則論として
DDDとかのレジスタ番号の1つとして、(HL)が書いてあり、
それがDDD=6だったと思う。
ただし、原則論なので、全ての命令でDDD=6にすれば必ず合法で、
(HL)になるという意味ではない。
817デフォルトの名無しさん
2020/07/18(土) 13:51:52.21ID:HDs6SbLj818デフォルトの名無しさん
2020/07/18(土) 13:56:24.86ID:B9g40Bu1 76: ぼくのことわすれないで
819デフォルトの名無しさん
2020/07/18(土) 14:24:37.73ID:HDs6SbLj AND, OR, XOR, ADD, ADC, SUB, SBC, CP,
やローテート、シフト命令でも、レジスタ様の命令で、
レジスタ番号を6にすると、(HL)に対する命令と同じ
マシン語になっていることが分かる。
やローテート、シフト命令でも、レジスタ様の命令で、
レジスタ番号を6にすると、(HL)に対する命令と同じ
マシン語になっていることが分かる。
820デフォルトの名無しさん
2020/07/19(日) 04:45:05.98ID:1aVreze3 x86_64のアセンブラを始めようと思ってるのですが、レジスタの使い方を教えてください
以前、80286の頃だと、たとえばECXレジスタはカウンタ用に使うものだったと記憶してますが
x86_64だとほぼもう汎用レジスタとして使えるように見えます
gccなどもx86_64用でもそういうコードを出力するようです
昔の用途での使い方について、どれくらい意識した方がよいのでしょう
以前、80286の頃だと、たとえばECXレジスタはカウンタ用に使うものだったと記憶してますが
x86_64だとほぼもう汎用レジスタとして使えるように見えます
gccなどもx86_64用でもそういうコードを出力するようです
昔の用途での使い方について、どれくらい意識した方がよいのでしょう
821デフォルトの名無しさん
2020/07/19(日) 10:17:20.71ID:TvRHHtME >>820
CPUの世代によっては、loop 命令は、
dec ecx
jnz ラベル名
とするよりも遅いことがあるので、後者の書き方の方が良い。
その意味で、ループカウンタを入れるレジスタとして、ecxにこだわる必要はない。
ただし、rep movsd などでは今でもカウンタが ecx に固定されている。
それ以外の場面では、ecxは、他の汎用レジスタと同じと考えてよい。
なお、ebpは汎用レジスタとしては使わず、スタックフレームの先頭アドレスを保持して、
ローカル変数をアクセスするために使うことが原則。
ただし、ローカル変数をebpの代わりにespを介してアクセスすることによって
ebpを汎用レジスタとして使う流儀も有り得る。
その場合は、push,pop命令によってespが変化してしまうので注意が必要となる。
なお、masmのlocalやarg擬似命令は、ebp方式を前提としている。
edi,esi は、movsd で使うことは意識しておく。
edx,eaxは、div命令で使うことを意識しておく。
edi,esi,ebpは、関数呼び出しで保存されるが、eax,ebx,ecx,edxは保存されないことを意識しておく。
eaxは関数呼び出しの戻り値になることを意識しておく。
CPUの世代によっては、loop 命令は、
dec ecx
jnz ラベル名
とするよりも遅いことがあるので、後者の書き方の方が良い。
その意味で、ループカウンタを入れるレジスタとして、ecxにこだわる必要はない。
ただし、rep movsd などでは今でもカウンタが ecx に固定されている。
それ以外の場面では、ecxは、他の汎用レジスタと同じと考えてよい。
なお、ebpは汎用レジスタとしては使わず、スタックフレームの先頭アドレスを保持して、
ローカル変数をアクセスするために使うことが原則。
ただし、ローカル変数をebpの代わりにespを介してアクセスすることによって
ebpを汎用レジスタとして使う流儀も有り得る。
その場合は、push,pop命令によってespが変化してしまうので注意が必要となる。
なお、masmのlocalやarg擬似命令は、ebp方式を前提としている。
edi,esi は、movsd で使うことは意識しておく。
edx,eaxは、div命令で使うことを意識しておく。
edi,esi,ebpは、関数呼び出しで保存されるが、eax,ebx,ecx,edxは保存されないことを意識しておく。
eaxは関数呼び出しの戻り値になることを意識しておく。
822デフォルトの名無しさん
2020/07/19(日) 10:18:46.24ID:TvRHHtME >>821
さらに、dec reg 命令より、sub reg,1 の方が速いことがある。
前者は2クロック、後者は1クロック。なので、loop文は、
sub ecx,1
jnz ラベル名
と書くのが最良。
さらに、dec reg 命令より、sub reg,1 の方が速いことがある。
前者は2クロック、後者は1クロック。なので、loop文は、
sub ecx,1
jnz ラベル名
と書くのが最良。
823デフォルトの名無しさん
2020/07/19(日) 12:34:39.03ID:h5vFOzT4824デフォルトの名無しさん
2020/07/19(日) 12:36:44.38ID:h5vFOzT4 レジスタが増えてるし
SIMDレジスタもあるんで
自由度は高い
MULとDIVは相変わらずRAX, RDX縛りがあるけど
SIMDレジスタもあるんで
自由度は高い
MULとDIVは相変わらずRAX, RDX縛りがあるけど
825デフォルトの名無しさん
2020/07/19(日) 12:47:27.95ID:du465xO7 IA-32の命令ならインテルのhpにある
826デフォルトの名無しさん
2020/07/19(日) 14:46:51.74ID:1aVreze3 820です
回答ありがとうございました
ABIやライブラリ等での使い方・縛りを考慮して使うようにすると、
やはりそれぞれのレジスタをアキュムレータ、カウンタ等として使う、
というのを指針にした方がよさそうですね
回答ありがとうございました
ABIやライブラリ等での使い方・縛りを考慮して使うようにすると、
やはりそれぞれのレジスタをアキュムレータ、カウンタ等として使う、
というのを指針にした方がよさそうですね
827デフォルトの名無しさん
2020/07/19(日) 15:35:41.18ID:AazHQwx2828デフォルトの名無しさん
2020/07/21(火) 11:55:19.37ID:08cjL+93 こんな感じで部品並べたら子ーどがてせきるやつないの?
amd64の
https://i.imgur.com/REDBsNI.png
https://i.imgur.com/NUN7ejI.png
https://i.imgur.com/Qchpsl1.png
amd64の
https://i.imgur.com/REDBsNI.png
https://i.imgur.com/NUN7ejI.png
https://i.imgur.com/Qchpsl1.png
829デフォルトの名無しさん
2020/07/27(月) 04:16:34.73ID:FDPJJmZc ない
830デフォルトの名無しさん
2020/08/03(月) 23:51:00.41ID:f8ly6bXL ttps://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%AC%E3%83%83%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%A2%E3%83%BC%E3%83%89
>アドレッシングモード
>既に使われなくなったアドレッシングモード
>メモリマップド・レジスタ
???国内なら78K0R(現RL78)、海外でもMSC-51(現EFM8BB1)とかはCPUのレジスタがメモリ空間にマッピングされている
いずれも現行製品では
>アドレッシングモード
>既に使われなくなったアドレッシングモード
>メモリマップド・レジスタ
???国内なら78K0R(現RL78)、海外でもMSC-51(現EFM8BB1)とかはCPUのレジスタがメモリ空間にマッピングされている
いずれも現行製品では
831デフォルトの名無しさん
2020/08/04(火) 10:47:29.79ID:DzQriKoF 6809の0-255あたりのやつのことかな
832デフォルトの名無しさん
2020/08/04(火) 10:48:39.15ID:DzQriKoF まあ同じことなんだろうけど
「CPUのレジスタがメモリ空間にマッピングされている」
というより
「メモリ空間がCPUのレジスタにマッピングされている」
というイメージ
「CPUのレジスタがメモリ空間にマッピングされている」
というより
「メモリ空間がCPUのレジスタにマッピングされている」
というイメージ
833デフォルトの名無しさん
2020/08/04(火) 11:41:48.61ID:WjyA4gdt イメージって何か表現してるようで何も言ってないに等しい
834デフォルトの名無しさん
2020/08/04(火) 12:45:04.95ID:g9THIEhB ttps://ednjapan.com/edn/articles/1908/28/news026_3.html
STMはレジスタとSRAMの構造が違うらしい
理由からすると多くのCPUが同じ事やってそう
STMはレジスタとSRAMの構造が違うらしい
理由からすると多くのCPUが同じ事やってそう
835デフォルトの名無しさん
2020/08/04(火) 13:23:59.89ID:9WSBhL2x この板でイメージを厳密に技術用語で使わないやつは…
836デフォルトの名無しさん
2020/08/04(火) 15:05:26.21ID:z2HwYjyf >>830
> CPUのレジスタがメモリ空間にマッピング
て具体的にどうやるんだろ?と思って調べてみた。
CPUのアドレスバスを監視して、レジスタにアクセスがあったのを検知したら、
それにマップされてるメモリにも同じようにアクセスするってことをしてると。なるほど。
> CPUのレジスタがメモリ空間にマッピング
て具体的にどうやるんだろ?と思って調べてみた。
CPUのアドレスバスを監視して、レジスタにアクセスがあったのを検知したら、
それにマップされてるメモリにも同じようにアクセスするってことをしてると。なるほど。
837デフォルトの名無しさん
2020/08/04(火) 15:22:33.51ID:CK7AS0VE >>836
そういうことではなく、レジスタをアドレス空間にマッピングしているCPUは、
例えば、アドレス空間の 0〜255 番地の部分をレジスタ専用に
して、CPUの外部のアドレスバスには信号が出ないようにしていることが多い。
そして、
mov [0],値
と書くと、r0 に「値」を書き込むようにCPUが設計されていて、
外部のDRAMなどには全く信号が送られないようになっている。
そういうことではなく、レジスタをアドレス空間にマッピングしているCPUは、
例えば、アドレス空間の 0〜255 番地の部分をレジスタ専用に
して、CPUの外部のアドレスバスには信号が出ないようにしていることが多い。
そして、
mov [0],値
と書くと、r0 に「値」を書き込むようにCPUが設計されていて、
外部のDRAMなどには全く信号が送られないようになっている。
838デフォルトの名無しさん
2020/08/04(火) 15:30:51.43ID:z2HwYjyf >>837
そういうのもあるだろうけど、それは最初からそういう設計にしているからそう動くということだよね。
アドレス空間にある入出力領域は固定的である必要はないので、バスに出た信号をどう処理するかは
設計者が自由に決められるはず。なので、バスに出た信号をメモリだけに送ることもできるし、
CPUとメモリ両方に送ることもできる。用途に合わせればいいということかと。
そういうのもあるだろうけど、それは最初からそういう設計にしているからそう動くということだよね。
アドレス空間にある入出力領域は固定的である必要はないので、バスに出た信号をどう処理するかは
設計者が自由に決められるはず。なので、バスに出た信号をメモリだけに送ることもできるし、
CPUとメモリ両方に送ることもできる。用途に合わせればいいということかと。
839デフォルトの名無しさん
2020/08/04(火) 15:34:19.50ID:CK7AS0VE840デフォルトの名無しさん
2020/08/04(火) 16:20:06.60ID:z2HwYjyf841デフォルトの名無しさん
2020/08/04(火) 19:31:24.43ID:aUyBUHRY >>837
ああ、ずっと何の話をしてるのか分からなかったけど0ページの話ね。
ああ、ずっと何の話をしてるのか分からなかったけど0ページの話ね。
842デフォルトの名無しさん
2020/08/16(日) 16:21:04.44ID:Cqk7CoxF >>839 アルディーノのCPUがそれだ。レジスタがメモリにマッピングされている。
843デフォルトの名無しさん
2020/08/17(月) 08:09:56.01ID:tzd42ouk LLVMが吐き出したx86-64アセンブラコードを入力とするツールを作りたいのですが
このアセンブラコードの文法に関する資料って何処にあるんでしょうか
ttps://llvm.org/docs/Extensions.html
ttps://sourceware.org/binutils/docs/as/
あたりにも各命令をどのように記述するかまでは載っていないように見えるのですが・・・
このアセンブラコードの文法に関する資料って何処にあるんでしょうか
ttps://llvm.org/docs/Extensions.html
ttps://sourceware.org/binutils/docs/as/
あたりにも各命令をどのように記述するかまでは載っていないように見えるのですが・・・
844デフォルトの名無しさん
2020/08/17(月) 10:11:33.24ID:RiKJFl8Z 命令セットレベルの話ならインテルのマニュアルでも見ろとしか。
845デフォルトの名無しさん
2020/08/17(月) 11:34:25.89ID:NVTg5S9X >>843
Intelに大量の PDF マニュアルがあり、詳細に書いてある。
Intelに大量の PDF マニュアルがあり、詳細に書いてある。
846デフォルトの名無しさん
2020/08/17(月) 11:37:24.90ID:NVTg5S9X >>843
LLVMツールの出力する、native の x86 や x64 のアセンブリコードは、
試してみる限り、masm 形式ではない。
見た目はgccの形式に似ている。
LLVMのarm版が出力したnativeアセンブリコードは、gccのgasが解釈して正しくobjファイル
までアセンブルできたことがある。
x86 や x64 の場合は、そこまでは試していない。
LLVMツールの出力する、native の x86 や x64 のアセンブリコードは、
試してみる限り、masm 形式ではない。
見た目はgccの形式に似ている。
LLVMのarm版が出力したnativeアセンブリコードは、gccのgasが解釈して正しくobjファイル
までアセンブルできたことがある。
x86 や x64 の場合は、そこまでは試していない。
847843
2020/08/17(月) 12:59:34.65ID:WGW93JMF848デフォルトの名無しさん
2020/08/18(火) 01:12:29.19ID:xqTakpBf >>847
命令表記は、8バイトのオペランド(や型)を表すのにdqwordとowordで表す
2つの流儀がある。
さらに、mmwordを使う流儀もあるが、浮動小数点演算のx87の文化では
浮動小数点でも専用の型名は無くて、dwordでfloat、qwordでdoubleを扱う
流儀があった。
そこにxmmやmmxのためだけにmmwordを持ってきた意図やセンスは
賛否が分かれるところだと思う。
命令表記は、8バイトのオペランド(や型)を表すのにdqwordとowordで表す
2つの流儀がある。
さらに、mmwordを使う流儀もあるが、浮動小数点演算のx87の文化では
浮動小数点でも専用の型名は無くて、dwordでfloat、qwordでdoubleを扱う
流儀があった。
そこにxmmやmmxのためだけにmmwordを持ってきた意図やセンスは
賛否が分かれるところだと思う。
849デフォルトの名無しさん
2020/08/18(火) 01:28:37.97ID:xqTakpBf >>847
x64のリファレンスは、原則的にAMDで、AMDにも詳しいマニュアルがある。
命令表記は、絶対アドレス addr に対する間接参照で、昔は、[addr]と
表記していたものが、x64だと、マシン語レベルでは絶対アドレスを埋め込まずに、
ripからの相対アドレスrel_addrを用いて、[rip+rel_addr]のような意味になっている
があるが、アセンブラレベルでそれを表記する時、どうするかと言う問題がある。
masmだと昔から、
mov eax,MyWork1
・・・
ret
MyWork dd 1234
と書いてきた。普通のアセンブラなら、
mov eax,[MyWork1]
・・・
ret
MyWork: dd 1234
と書くところを。
しかし、rip相対になった場合、
mov eax,[rip+MyWork]
と書くと意味に合わないし、かと言って、
mov eax,[rip+rel MyWork]
と書くのも長くなる。意味的には、Masmだと
mov eax,MyWork
なのだが、マシン語レベルでは、絶対アドレス/相対アドレスのどちらで表現されるか、
明確に表すことはできなくなるジレンマがある。
x64のリファレンスは、原則的にAMDで、AMDにも詳しいマニュアルがある。
命令表記は、絶対アドレス addr に対する間接参照で、昔は、[addr]と
表記していたものが、x64だと、マシン語レベルでは絶対アドレスを埋め込まずに、
ripからの相対アドレスrel_addrを用いて、[rip+rel_addr]のような意味になっている
があるが、アセンブラレベルでそれを表記する時、どうするかと言う問題がある。
masmだと昔から、
mov eax,MyWork1
・・・
ret
MyWork dd 1234
と書いてきた。普通のアセンブラなら、
mov eax,[MyWork1]
・・・
ret
MyWork: dd 1234
と書くところを。
しかし、rip相対になった場合、
mov eax,[rip+MyWork]
と書くと意味に合わないし、かと言って、
mov eax,[rip+rel MyWork]
と書くのも長くなる。意味的には、Masmだと
mov eax,MyWork
なのだが、マシン語レベルでは、絶対アドレス/相対アドレスのどちらで表現されるか、
明確に表すことはできなくなるジレンマがある。
850デフォルトの名無しさん
2020/08/21(金) 15:25:03.93ID:EskYTmRE destにメモリを指定できる命令ってパイプラインをストールさせやすいように思うけどそんな事はないの?
x64だと
ADD r/m64,r64
みたいなの
x64だと
ADD r/m64,r64
みたいなの
851デフォルトの名無しさん
2020/08/21(金) 20:30:50.01ID:+dwilF/E 確かにストールしやすいとは言えるが影響度合いはプロセッサ次第で、そういう命令を持ったプロセッサはちゃんと考慮した設計がされている。
例えばOut of Order実行を行うプロセッサはパイプラインに結果書込み待ちをするキューを持ったステージがあって、メモリ書き込み前に後続の命令を実行可能だから単純にストールはしない。
前後の命令に依存があればストールするのはレジスタ相手でも同じことだし、命令でロードとモディファイとストアを分けても実行する内容は同じなのだから、結局はプロセッサアーキテクチャ毎に最適化が必要なことには変わりがない。
例えばOut of Order実行を行うプロセッサはパイプラインに結果書込み待ちをするキューを持ったステージがあって、メモリ書き込み前に後続の命令を実行可能だから単純にストールはしない。
前後の命令に依存があればストールするのはレジスタ相手でも同じことだし、命令でロードとモディファイとストアを分けても実行する内容は同じなのだから、結局はプロセッサアーキテクチャ毎に最適化が必要なことには変わりがない。
852デフォルトの名無しさん
2020/08/22(土) 00:25:14.47ID:Rco6UMRM インテル(R) 64 アーキテクチャーおよび IA-32 アーキテクチャー最適化リファレンス・マニュアル
を良く呼んだら書いてあったわ
> 一般的に、各命令を構成するマイクロオペレーション(μOP)の数を考慮し、単一マイク
> ロオペレーション(μOP)の命令、4 マイクロオペレーション(μOP)未満の単純な命令、
> マイクロシーケンサー ROM が必要な命令の順で優先して、命令を選択すると良い。
> 〜
> ・複数のマイクロオペレーション(μOP)からなる一連の命令を分割できない場合は、
> 同等の異なる命令シーケンスに分割する。例えば、読み出し−変更−書き込み命令は、
> 読み出し−変更命令 + ストア命令に分割すると、高速化が可能である。この手法を利
> 用すれば、新しいコードシーケンスが元のコードシーケンスより大きくなった場合で
> も、パフォーマンスが向上する。
らしいのでADD m64,r64みたいな命令はパフォーマンス上のデメリットがあるから使用を控えた方が良さそう
を良く呼んだら書いてあったわ
> 一般的に、各命令を構成するマイクロオペレーション(μOP)の数を考慮し、単一マイク
> ロオペレーション(μOP)の命令、4 マイクロオペレーション(μOP)未満の単純な命令、
> マイクロシーケンサー ROM が必要な命令の順で優先して、命令を選択すると良い。
> 〜
> ・複数のマイクロオペレーション(μOP)からなる一連の命令を分割できない場合は、
> 同等の異なる命令シーケンスに分割する。例えば、読み出し−変更−書き込み命令は、
> 読み出し−変更命令 + ストア命令に分割すると、高速化が可能である。この手法を利
> 用すれば、新しいコードシーケンスが元のコードシーケンスより大きくなった場合で
> も、パフォーマンスが向上する。
らしいのでADD m64,r64みたいな命令はパフォーマンス上のデメリットがあるから使用を控えた方が良さそう
853デフォルトの名無しさん
2020/08/29(土) 02:13:33.36ID:kcJTulzj x64命令の動作を確認するのに対話式にアセンブル&実行&レジスタの確認が出来るツールとかないかな?
各値を変えながら試行錯誤したいけどソース書いてアセンブルしてデバッガに読み込んでステップ実行してだと手間すぎる
今MULのフラグの更新動作がAMDの資料を見てもIntelの資料を見てもググってももよく判らない
各値を変えながら試行錯誤したいけどソース書いてアセンブルしてデバッガに読み込んでステップ実行してだと手間すぎる
今MULのフラグの更新動作がAMDの資料を見てもIntelの資料を見てもググってももよく判らない
854デフォルトの名無しさん
2020/08/29(土) 17:42:02.36ID:CDQjtNyx855デフォルトの名無しさん
2020/08/29(土) 18:05:14.09ID:CDQjtNyx >>853
Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 2A:
Instruction Set Reference, A-M
-------------------------------------------------
[MUL—Unsigned Multiply]
・・・
Flags Affected
The OF and CF flags are set to 0 if the upper half of the result is 0; otherwise, they
are set to 1. The SF, ZF, AF, and PF flags are undefined.
Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 2A:
Instruction Set Reference, A-M
-------------------------------------------------
[MUL—Unsigned Multiply]
・・・
Flags Affected
The OF and CF flags are set to 0 if the upper half of the result is 0; otherwise, they
are set to 1. The SF, ZF, AF, and PF flags are undefined.
856デフォルトの名無しさん
2020/08/29(土) 18:39:05.44ID:kcJTulzj >>855
その文章は確認していてAMD64のドキュメントにも
>If the upper half of the product is non-zero, the instruction sets the carry flag (CF) and overflow flag
>(OF) both to 1. Otherwise, it clears CF and OF to 0.
と似たような記述があるんだけど双方の資料に書いてある"upper half"がどの部分を示しているのか判らない
演算結果の上半分が入るDレジスタの事?
その文章は確認していてAMD64のドキュメントにも
>If the upper half of the product is non-zero, the instruction sets the carry flag (CF) and overflow flag
>(OF) both to 1. Otherwise, it clears CF and OF to 0.
と似たような記述があるんだけど双方の資料に書いてある"upper half"がどの部分を示しているのか判らない
演算結果の上半分が入るDレジスタの事?
857デフォルトの名無しさん
2020/08/29(土) 19:05:00.05ID:CGaweZC2 >>856
Intelの日本語マニュアルには処理の疑似コードが載ってる。
これによると、上半分というのは、各命令で使うレジスタサイズの上半分とわかる。
8,16,32bitそれぞれ場合によって上半分の長さが変わるのでそう書くしかない。
だから64bitの場合の上半分は上位32bitになる。
操作
IF (NumberOfOperands = 1)
THEN IF (OperandSize = 8)
THEN
AX ← AL ? SRC (* signed multiplication *)
IF AL = AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE IF OperandSize = 16
THEN
DX:AX ← AX ? SRC (* signed multiplication *)
IF sign_extend_to_32 (AX) = DX:AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE (* OperandSize = 32 *)
EDX:EAX ← EAX ? SRC (* signed multiplication *)
IF EAX = EDX:EAX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
FI;
Intelの日本語マニュアルには処理の疑似コードが載ってる。
これによると、上半分というのは、各命令で使うレジスタサイズの上半分とわかる。
8,16,32bitそれぞれ場合によって上半分の長さが変わるのでそう書くしかない。
だから64bitの場合の上半分は上位32bitになる。
操作
IF (NumberOfOperands = 1)
THEN IF (OperandSize = 8)
THEN
AX ← AL ? SRC (* signed multiplication *)
IF AL = AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE IF OperandSize = 16
THEN
DX:AX ← AX ? SRC (* signed multiplication *)
IF sign_extend_to_32 (AX) = DX:AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
ELSE (* OperandSize = 32 *)
EDX:EAX ← EAX ? SRC (* signed multiplication *)
IF EAX = EDX:EAX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
FI;
858デフォルトの名無しさん
2020/08/29(土) 19:47:52.94ID:cC8g9MrB upper half of the product だから乗算結果の上半分だ。
疑問の余地は無いと思うがな…
疑問の余地は無いと思うがな…
859蟻人間 ◆T6xkBnTXz7B0
2020/08/29(土) 20:22:30.40ID:GYyhmMZY CPU emulator Unicorn
https://www.unicorn-engine.org/
https://www.unicorn-engine.org/
860デフォルトの名無しさん
2020/08/30(日) 01:05:43.21ID:BjChy3oe IF sign_extend_to_32 (AX) = DX:AX
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
これだと符号拡張したものと比較しているから、言葉による説明と違っている。
基本的に、mulは、符号無しの整数に対する掛け算なのだが。
THEN CF ← 0; OF ← 0;
ELSE CF ← 1; OF ← 1;
FI;
これだと符号拡張したものと比較しているから、言葉による説明と違っている。
基本的に、mulは、符号無しの整数に対する掛け算なのだが。
861デフォルトの名無しさん
2020/08/30(日) 01:11:49.03ID:BjChy3oe >>857
それは、mul(符号無し掛け算)ではなく、imul(符号付掛け算)の擬似コードで、
英語版でも、同じような擬似コードが書いてあり、言葉による説明は、
次のようになっている:
Flags Affected
For the one operand form of the instruction, the CF and OF flags are set when signif-
icant bits are carried into the upper half of the result and cleared when the result fits
exactly in the lower half of the result. For the two- and three-operand forms of the
instruction, the CF and OF flags are set when the result must be truncated to fit in the
destination operand size and cleared when the result fits exactly in the destination
operand size. The SF, ZF, AF, and PF flags are undefined.
それは、mul(符号無し掛け算)ではなく、imul(符号付掛け算)の擬似コードで、
英語版でも、同じような擬似コードが書いてあり、言葉による説明は、
次のようになっている:
Flags Affected
For the one operand form of the instruction, the CF and OF flags are set when signif-
icant bits are carried into the upper half of the result and cleared when the result fits
exactly in the lower half of the result. For the two- and three-operand forms of the
instruction, the CF and OF flags are set when the result must be truncated to fit in the
destination operand size and cleared when the result fits exactly in the destination
operand size. The SF, ZF, AF, and PF flags are undefined.
862デフォルトの名無しさん
2020/08/30(日) 01:22:29.16ID:BjChy3oe ちなみに、同じビット数の2つの整数の掛け算は、結果の内、掛ける前の整数の
ビット数の部分に限定した部分だけを見れば、符号付き掛け算と符号無し掛け算
で結果が変わらない。
一方、imulは、2オペランド以上のものは、結果のビット数が、掛ける前と同じ。
そして、mulは、2オペランド以上のものが用意されて無い。
これは、最初に述べた性質から、imulとmulで、2オペランド以上の場合では、
結果が変わらなくなってしまうため、imulだけで、符号無し掛け算にも対応できる
ためである。
ビット数の部分に限定した部分だけを見れば、符号付き掛け算と符号無し掛け算
で結果が変わらない。
一方、imulは、2オペランド以上のものは、結果のビット数が、掛ける前と同じ。
そして、mulは、2オペランド以上のものが用意されて無い。
これは、最初に述べた性質から、imulとmulで、2オペランド以上の場合では、
結果が変わらなくなってしまうため、imulだけで、符号無し掛け算にも対応できる
ためである。
863デフォルトの名無しさん
2020/08/30(日) 14:10:51.87ID:GgAZZaQa864デフォルトの名無しさん
2020/08/30(日) 14:26:36.90ID:EVylyaDc865デフォルトの名無しさん
2020/08/30(日) 18:38:46.61ID:Oy/VxFsh おっぱいしか目に入らん
866デフォルトの名無しさん
2020/08/31(月) 15:24:59.40ID:r6h0vUdb セクションとかも理解してくれるx64逆アセンブラとかないのかな
セクション情報やデバッグ情報をディレクティブ等でコードと一緒に出力してくれるとうれしい
セクション情報やデバッグ情報をディレクティブ等でコードと一緒に出力してくれるとうれしい
867デフォルトの名無しさん
2020/09/01(火) 10:42:01.73ID:vwihzMdy >>864
昔は子供向けのベーマガに載ってるレベル。
昔は子供向けのベーマガに載ってるレベル。
868デフォルトの名無しさん
2020/09/01(火) 17:43:15.76ID:8L3AfpS1 >>866
Linux?
Linux?
869デフォルトの名無しさん
2020/09/03(木) 12:52:56.48ID:ZDuIxl5I870デフォルトの名無しさん
2020/09/03(木) 14:20:08.59ID:cueCbpYZ871デフォルトの名無しさん
2020/09/04(金) 10:09:14.61ID:KmpQA39o >>870
今時ネット通販だろうけど本屋と同じで
たまたま近くに置いてあるのに目が止まるのが良かったりするんだけどな
パートおばさんのハンダ付け作業なんて若年化する前にほぼ中国海外にいったろう
最近は新入社員研修に後ろから二人羽織状態で手を握りながら・・
今時ネット通販だろうけど本屋と同じで
たまたま近くに置いてあるのに目が止まるのが良かったりするんだけどな
パートおばさんのハンダ付け作業なんて若年化する前にほぼ中国海外にいったろう
最近は新入社員研修に後ろから二人羽織状態で手を握りながら・・
872デフォルトの名無しさん
2020/09/06(日) 06:21:38.35ID:EKeL4GkH ドキュメント72時間で秋葉原の部品屋やってたけど
女子高生がオリジナルのペンライトを作るために来てた
女子高生がオリジナルのペンライトを作るために来てた
873デフォルトの名無しさん
2020/09/06(日) 09:40:26.46ID:TNZ7/NP8 良スレ
874デフォルトの名無しさん
2020/09/07(月) 16:54:29.21ID:0bCSYOR0875デフォルトの名無しさん
2020/09/07(月) 17:52:16.84ID:0w2E3x4d >>874
撮影用のモデルだろ、半田が付いているのは裏面だ
撮影用のモデルだろ、半田が付いているのは裏面だ
876デフォルトの名無しさん
2020/09/07(月) 18:30:23.60ID:3pB/Wjpj それ以前に火傷する
877デフォルトの名無しさん
2020/09/07(月) 18:41:49.64ID:hcXGR9uA878デフォルトの名無しさん
2020/09/07(月) 22:17:45.58ID:KQEAaFWf 半田ごてを持つ部分が間違ってるし、基盤もハンダ付けする面は上下逆だし、
さあに、こういう基盤は、最近ではかなりの部分がロボットでハンダ付けしてると
聞いている。
さあに、こういう基盤は、最近ではかなりの部分がロボットでハンダ付けしてると
聞いている。
879デフォルトの名無しさん
2020/09/07(月) 22:44:57.51ID:0w2E3x4d880デフォルトの名無しさん
2020/09/08(火) 03:25:35.85ID:jacy6RM2 何周遅れか判らんくらい激しく概出過ぎてつまらん
881デフォルトの名無しさん
2020/09/09(水) 19:36:30.15ID:HmJqfQ+A >>875
そっちにもつっこみ所あったんか…今頃知った
そっちにもつっこみ所あったんか…今頃知った
882デフォルトの名無しさん
2020/09/13(日) 00:55:43.99ID:NuGQj3YA 論理演算より、鼻筋の整形が気になって・・・
883デフォルトの名無しさん
2020/09/25(金) 21:12:03.86ID:1nrszLVg 鼻の穴にもつっこむ所あったんか…
884デフォルトの名無しさん
2020/11/02(月) 22:13:42.36ID:KqjMEGzA 775にしてはアルミ電解バリバリだな
885デフォルトの名無しさん
2020/11/19(木) 16:32:15.09ID:7GrsSxFi アセンブラからドライバを読みたいですが、どうやってしますか?
886デフォルトの名無しさん
2020/11/19(木) 20:17:00.91ID:4w1/CW5J 日本語が変
887デフォルトの名無しさん
2020/11/25(水) 09:47:14.54ID:gT5in2ls 好奇心でMS-DOS 6.2にJWasmを入れてアセンブラ入門サイトを見ながら学習しています。
大きな値を10進変換したい場合はどうすれば良いのでしょう?
DX:AX ÷ 10dがしたい。
INT21hファンクションコールでAH=36hを実行してAX * BX * CXした結果を
DIV 10するのに、商が16ビットを超えるので例外が発生する。
入門中なので、2バイトまでの環境しか使い方がわかりません。
4バイトのレジスタが使えれば解決する話なのかも知れませんけど、、
DX:AXから計算する方法ないか調べています。
結局、EDX:EAXを10dで割る事になっても同じことが起きるので
大きな値を10進変換したい場合はどうすれば良いのでしょう?
DX:AX ÷ 10dがしたい。
INT21hファンクションコールでAH=36hを実行してAX * BX * CXした結果を
DIV 10するのに、商が16ビットを超えるので例外が発生する。
入門中なので、2バイトまでの環境しか使い方がわかりません。
4バイトのレジスタが使えれば解決する話なのかも知れませんけど、、
DX:AXから計算する方法ないか調べています。
結局、EDX:EAXを10dで割る事になっても同じことが起きるので
888デフォルトの名無しさん
2020/11/25(水) 12:44:21.97ID:jzvQX9aE >>887
(1)まず、DXを10で割る。
その時の商をQ1(ax),余りをR1(dx)とする。
(2)
mov ax,元のAX
xor dx,dx ;← dx=0
add ax,R1
adc dx,0
とする。これは、元のAXにR1を足したものを(dx:ax)に入れていることに相当する。
(3)
(dx:ax)を10で割り、商をQ2(ax)、余りをR2(dx)とする。
(4) 最終的な商Qは、(Q1:Q2), 余りRは、R2である。
(1)まず、DXを10で割る。
その時の商をQ1(ax),余りをR1(dx)とする。
(2)
mov ax,元のAX
xor dx,dx ;← dx=0
add ax,R1
adc dx,0
とする。これは、元のAXにR1を足したものを(dx:ax)に入れていることに相当する。
(3)
(dx:ax)を10で割り、商をQ2(ax)、余りをR2(dx)とする。
(4) 最終的な商Qは、(Q1:Q2), 余りRは、R2である。
889デフォルトの名無しさん
2020/11/25(水) 12:46:48.67ID:jzvQX9aE890デフォルトの名無しさん
2020/11/25(水) 12:50:41.35ID:jzvQX9aE コードに直すとこうなると思う。
;入力: (dx:ax)
;出力: (Q1:ax)=商, 余り=dx
mov original_ax,ax
mov ax,dx
xor dx,dx
mov cx,10
div cx
mov Q1,ax
mov ax,original_ax
div cx
;商=(Q1:ax), 余り=dx
ret
;入力: (dx:ax)
;出力: (Q1:ax)=商, 余り=dx
mov original_ax,ax
mov ax,dx
xor dx,dx
mov cx,10
div cx
mov Q1,ax
mov ax,original_ax
div cx
;商=(Q1:ax), 余り=dx
ret
891デフォルトの名無しさん
2020/11/25(水) 13:07:31.94ID:jzvQX9aE >>887
32BIT(4バイト)命令を使っていいなら、(dx:ax)/10 は、
shl edx,16
mov dx,ax
mov eax,edx
xor edx,edx
mov ecx,10
idiv ecx
で、eax に32BITの商、edx に余り(0〜9)が出る。
32BIT(4バイト)命令を使っていいなら、(dx:ax)/10 は、
shl edx,16
mov dx,ax
mov eax,edx
xor edx,edx
mov ecx,10
idiv ecx
で、eax に32BITの商、edx に余り(0〜9)が出る。
892デフォルトの名無しさん
2020/11/25(水) 13:12:20.82ID:jzvQX9aE >>891
idivじゃなくて、divが正しい。
idivじゃなくて、divが正しい。
893デフォルトの名無しさん
2020/11/25(水) 14:53:28.45ID:h9isg/D4 定数の除算に糞遅いDIV命令を使うとか
894デフォルトの名無しさん
2020/11/25(水) 14:55:43.27ID:gT5in2ls MUL BX
MUL CX
MOV Q2, DX
MOV Q1, AX
MOV BX, 10
DIV_LOOP:
XOR DX, DX
MOV AX, Q2
DIV BX
MOV Q2, AX
MOV AX, Q1
DIV BX
MOV Q1, AX
ADD DX, '0'
PUSH DX
OR AX, AX
JNZ DIV_LOOP
こんな感じですか?
気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
MUL CX
MOV Q2, DX
MOV Q1, AX
MOV BX, 10
DIV_LOOP:
XOR DX, DX
MOV AX, Q2
DIV BX
MOV Q2, AX
MOV AX, Q1
DIV BX
MOV Q1, AX
ADD DX, '0'
PUSH DX
OR AX, AX
JNZ DIV_LOOP
こんな感じですか?
気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
895デフォルトの名無しさん
2020/11/25(水) 15:47:06.05ID:T5VOSp5s 速いから
ではないでしょ
ではないでしょ
896デフォルトの名無しさん
2020/11/25(水) 16:46:45.83ID:jzvQX9aE >>894
>気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
>CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
昔は速かったので今でも伝統的に0を代入する変わりにxor reg,regを
使い、cmp ax,0の変わりに or ax,axを使う人が多い。
しかし、その「昔」とは、80486とかよりもずっと昔の初代8086の時代のことかもしれない。
ただし、xor reg,regだとフラグ類まで初期化されてしまうので、mov reg,0を使った方が
良い場合がある。
>>895
今は速くは無いが、昔は速かった。
その伝統が何故か今でも継承されている。
>気になったのですが、MOV DX, 0ではなくて、XOR DX, DXなのは処理が速いから?
>CMP AX, 0よりも、OR AX, AXの方が良いのでしょうか?
昔は速かったので今でも伝統的に0を代入する変わりにxor reg,regを
使い、cmp ax,0の変わりに or ax,axを使う人が多い。
しかし、その「昔」とは、80486とかよりもずっと昔の初代8086の時代のことかもしれない。
ただし、xor reg,regだとフラグ類まで初期化されてしまうので、mov reg,0を使った方が
良い場合がある。
>>895
今は速くは無いが、昔は速かった。
その伝統が何故か今でも継承されている。
897デフォルトの名無しさん
2020/11/25(水) 16:58:10.99ID:jzvQX9aE >>894
冒頭の
MUL BX
MUL CX
の部分が怪しい。一行目で結果がDX:AXに入っているのに、二行目ではそれを
無視しているが、無視してはいけない。
また、最後の
OR AX, AX
JNZ DIV_LOOP
の判定は間違い。
これだと、Q2がまだ非0の場合にもループが終わってしまう。
ちゃんと、Q2が非0の場合もループを続行しなくてはならない。
また、Qは、商(quotient)の頭文字を使っただけで、伝統的には、
意味が余り分からない変数は、work1 などを使う慣例があったりする。
意味が分かる場合には、意味が分かるような変数名にする。
冒頭の
MUL BX
MUL CX
の部分が怪しい。一行目で結果がDX:AXに入っているのに、二行目ではそれを
無視しているが、無視してはいけない。
また、最後の
OR AX, AX
JNZ DIV_LOOP
の判定は間違い。
これだと、Q2がまだ非0の場合にもループが終わってしまう。
ちゃんと、Q2が非0の場合もループを続行しなくてはならない。
また、Qは、商(quotient)の頭文字を使っただけで、伝統的には、
意味が余り分からない変数は、work1 などを使う慣例があったりする。
意味が分かる場合には、意味が分かるような変数名にする。
898デフォルトの名無しさん
2020/11/25(水) 17:02:18.40ID:jzvQX9aE なお、Q1は、説明の都合上、数学と似た感覚で短い変数を付けたが、
アセンブラなどに書く場合には、もっと長い名前にした方がいい。
短いとアセンブラが何かと混同して問題になるかも知れないから。
例えば、レジスタ名にr1などというものがある場合があるので注意。
アセンブラなどに書く場合には、もっと長い名前にした方がいい。
短いとアセンブラが何かと混同して問題になるかも知れないから。
例えば、レジスタ名にr1などというものがある場合があるので注意。
899デフォルトの名無しさん
2020/11/25(水) 17:44:43.84ID:h9isg/D4900デフォルトの名無しさん
2020/11/26(木) 00:21:00.79ID:5BVCYzUa 皆知ってるてのになw
901デフォルトの名無しさん
2020/11/26(木) 01:11:06.89ID:lH6B10sG >>899
では、現在のIntelCPUにおいて、
・mov reg,0の代わりにxor reg,reg
・cmp eax,0の変わりにor eax,eax
を使うメリットをそれぞれ書いてみてください。
では、現在のIntelCPUにおいて、
・mov reg,0の代わりにxor reg,reg
・cmp eax,0の変わりにor eax,eax
を使うメリットをそれぞれ書いてみてください。
902デフォルトの名無しさん
2020/11/26(木) 12:23:04.16ID:kAbnbrOP # mk_src.rb
def mk_src( md, loop1 = 1000000, loop2 = 1000 )
tit, fpath, asm_str = case md
when 1; [ 'imd', 'imd.c', %Q{\t\tasm( "movl $0, %eax\\ncmpl $0, %eax" );\n} ]
when 2; [ 'reg', 'reg.c', %Q{\t\tasm( "xorl %eax, %eax\\norl %eax, %eax" );\n} ]
end
File.open( fpath, 'w:UTF-8' ){|fh|
fh.print <<_EOT_
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int main(void)
{
LARGE_INTEGER qpff, qpf0, qpf1;
QueryPerformanceFrequency( &qpff );
unsigned int n = #{loop2};
QueryPerformanceCounter( &qpf0 );
while( n-- ){
#{asm_str * loop1}
}
QueryPerformanceCounter( &qpf1 );
printf( " #{tit}. time %lf[ms]\\n", (double)(qpf1.QuadPart - qpf0.QuadPart) * 1000.0 / qpff.QuadPart );
return 0;
}
_EOT_
} # File.open
end
mk_src( 1 )
mk_src( 2 )
def mk_src( md, loop1 = 1000000, loop2 = 1000 )
tit, fpath, asm_str = case md
when 1; [ 'imd', 'imd.c', %Q{\t\tasm( "movl $0, %eax\\ncmpl $0, %eax" );\n} ]
when 2; [ 'reg', 'reg.c', %Q{\t\tasm( "xorl %eax, %eax\\norl %eax, %eax" );\n} ]
end
File.open( fpath, 'w:UTF-8' ){|fh|
fh.print <<_EOT_
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
int main(void)
{
LARGE_INTEGER qpff, qpf0, qpf1;
QueryPerformanceFrequency( &qpff );
unsigned int n = #{loop2};
QueryPerformanceCounter( &qpf0 );
while( n-- ){
#{asm_str * loop1}
}
QueryPerformanceCounter( &qpf1 );
printf( " #{tit}. time %lf[ms]\\n", (double)(qpf1.QuadPart - qpf0.QuadPart) * 1000.0 / qpff.QuadPart );
return 0;
}
_EOT_
} # File.open
end
mk_src( 1 )
mk_src( 2 )
903デフォルトの名無しさん
2020/11/26(木) 12:23:28.07ID:kAbnbrOP $ uname -srvmo
MINGW64_NT-10.0-18363 3.1.7-340.x86_64 2020-09-22 20:54 UTC x86_64 Msys
$ gcc imd.c -O0 -o imd; gcc reg.c -O0 -o reg
8291652 imd.exe
6291780 reg.exe
$ ./imd.exe; ./imd.exe; ./imd.exe; ./imd.exe
imd. time 221.844800[ms]
imd. time 236.904100[ms]
imd. time 205.867200[ms]
imd. time 242.199800[ms]
$ ./reg.exe; ./reg.exe; ./reg.exe; ./reg.exe
reg. time 134.806000[ms]
reg. time 145.542900[ms]
reg. time 147.039100[ms]
reg. time 143.031100[ms]
MINGW64_NT-10.0-18363 3.1.7-340.x86_64 2020-09-22 20:54 UTC x86_64 Msys
$ gcc imd.c -O0 -o imd; gcc reg.c -O0 -o reg
8291652 imd.exe
6291780 reg.exe
$ ./imd.exe; ./imd.exe; ./imd.exe; ./imd.exe
imd. time 221.844800[ms]
imd. time 236.904100[ms]
imd. time 205.867200[ms]
imd. time 242.199800[ms]
$ ./reg.exe; ./reg.exe; ./reg.exe; ./reg.exe
reg. time 134.806000[ms]
reg. time 145.542900[ms]
reg. time 147.039100[ms]
reg. time 143.031100[ms]
904デフォルトの名無しさん
2020/11/26(木) 12:58:51.67ID:lH6B10sG Intelの最適化マニュアルを見たが、or,xor,cmp,movのlatencyやthroughputは
CPUによりマチマチで、絶対にどれが速いと言うようなことはいえないと思う。
ややこしいのは、movは、latencyが1や0.5, throughoutが0.5なのに対し、
xorは、latencyが1, throughtputが0.33や0.5となっていたりする。
これもCPUIDによってさまざま。
表の中のCPUIDの表記法も独特なので、どれが最新のCPUに対応しているのかも
個人的には今のところ分からない。
CPUによりマチマチで、絶対にどれが速いと言うようなことはいえないと思う。
ややこしいのは、movは、latencyが1や0.5, throughoutが0.5なのに対し、
xorは、latencyが1, throughtputが0.33や0.5となっていたりする。
これもCPUIDによってさまざま。
表の中のCPUIDの表記法も独特なので、どれが最新のCPUに対応しているのかも
個人的には今のところ分からない。
905デフォルトの名無しさん
2020/11/26(木) 13:10:05.83ID:Ndl69lfH906デフォルトの名無しさん
2020/11/26(木) 14:55:11.18ID:l8W6EZba 馬鹿ほど脳みそ足りないからAppleのようにすぐ互換性を捨てたがる。
そんな馬鹿は伝統を重んじてきたx86系を使わないでほしい。
そんな馬鹿は伝統を重んじてきたx86系を使わないでほしい。
907デフォルトの名無しさん
2020/11/26(木) 16:30:36.87ID:s+oX3EtE908デフォルトの名無しさん
2020/11/26(木) 18:31:44.20ID:b0/J9kY8 命令自体のクロック数は多少違うかもしれんがキャッシュ効率も考えれば1バイト命令のxor ax,axの方が正解の確率が高いと思うよ。
909デフォルトの名無しさん
2020/11/26(木) 18:39:31.62ID:rqBz/pid てかxor reg, regはIntelやAMDの最適化マニュアルにも書いてあるくらいなんだが
910デフォルトの名無しさん
2020/11/26(木) 18:48:11.36ID:HK02mgb4 x86は386,486,586,686と拡張されてきて、その度に命令が拡張されてきてる。これらはどれもx86だが、
これらの互換性を取ろうとすると386に合わせるしかなくなる。しかしそれでは今のWindowsは動かない。
一般の人にとって互換性というのは普段使っているアプリケーションが動けばいいので、それでほぼ支障ない。
最近のIntel CPUはHaswell、Broadwell、Skylake、Kebylakeと来ているが、これらの間だけ見ても
命令が拡張されているので完全な互換性はない。ならば互換性を重視して、最新CPUの便利な機能を使うな
ということになると技術者のレベルは昔のまま上がらないことになる。それは時代に取り残されることにならないか。
386はシングルコアだったが今はマルチコアが当たり前の時代だ。しかしソフトウェアは今でもシングルコアを
前提に書くことが多い。その方が簡単だしそれでも動くからだ。しかし、搭載されているコア数を最初に見て、
マルチコアだったら並列処理できるところは並列で動かせば早くなるのがわかっていても。互換性のために
わざとそうしないとしたらそれはただの怠慢に過ぎないだろう。そういう人はx86系を使わないでほしい。
これらの互換性を取ろうとすると386に合わせるしかなくなる。しかしそれでは今のWindowsは動かない。
一般の人にとって互換性というのは普段使っているアプリケーションが動けばいいので、それでほぼ支障ない。
最近のIntel CPUはHaswell、Broadwell、Skylake、Kebylakeと来ているが、これらの間だけ見ても
命令が拡張されているので完全な互換性はない。ならば互換性を重視して、最新CPUの便利な機能を使うな
ということになると技術者のレベルは昔のまま上がらないことになる。それは時代に取り残されることにならないか。
386はシングルコアだったが今はマルチコアが当たり前の時代だ。しかしソフトウェアは今でもシングルコアを
前提に書くことが多い。その方が簡単だしそれでも動くからだ。しかし、搭載されているコア数を最初に見て、
マルチコアだったら並列処理できるところは並列で動かせば早くなるのがわかっていても。互換性のために
わざとそうしないとしたらそれはただの怠慢に過ぎないだろう。そういう人はx86系を使わないでほしい。
911デフォルトの名無しさん
2020/11/26(木) 18:55:48.10ID:l8W6EZba このように互換性捨てろという奴は頭悪いとよく分かる。
PowerPC、IA64、MIPSから何も学んでないのだ。
PowerPC、IA64、MIPSから何も学んでないのだ。
912デフォルトの名無しさん
2020/11/26(木) 19:02:03.76ID:rqBz/pid x86を捨てたがっているのはIntel自身なんだよなぁ
913デフォルトの名無しさん
2020/11/26(木) 19:40:42.10ID:lH6B10sG914デフォルトの名無しさん
2020/11/26(木) 19:52:22.98ID:lH6B10sG >>909
今見てみたら、xor reg,reg や sub reg,reg には「実行依存性」を断ち切る効果が
あると書いてあった。Pentium 4 から特別な扱いをする様になったとか。
つまり、xor reg,regだとフラグまで初期化してしまうので、フラグが決まるまで
Latencyを待つ必要が無い。
ところが、mov reg,0だとフラグは引き継ぐから前の命令によってフラグが
決まるまで次の命令の実行が待たされることがあるのかな。
もしかしたら、CPU内部では、ZF,CF,SFなどと独立して変更できずに、
EFLAGS全体を1つのレジスタの様に扱うことが基本になっていて、
一部だけを変更しようとすると待機が発生しやすくなるのかもしれない。
今見てみたら、xor reg,reg や sub reg,reg には「実行依存性」を断ち切る効果が
あると書いてあった。Pentium 4 から特別な扱いをする様になったとか。
つまり、xor reg,regだとフラグまで初期化してしまうので、フラグが決まるまで
Latencyを待つ必要が無い。
ところが、mov reg,0だとフラグは引き継ぐから前の命令によってフラグが
決まるまで次の命令の実行が待たされることがあるのかな。
もしかしたら、CPU内部では、ZF,CF,SFなどと独立して変更できずに、
EFLAGS全体を1つのレジスタの様に扱うことが基本になっていて、
一部だけを変更しようとすると待機が発生しやすくなるのかもしれない。
915デフォルトの名無しさん
2020/11/26(木) 19:56:51.64ID:lH6B10sG >>914
スマン。
そういう意味ではないようだわ。
or eax,ebx
とかだと、直前までの命令でeaxとebxの両方のレジスタの値が決まってないと
パイプライン上でこの命令ALUのステージを実行することは出来ないので待機が
発生する。
ところが、xor eax,eax だと直前までの命令のeaxの結果がどうであれ、この
命令は必ずeaxを0にしてしまうから、待機する必要が無い、という意味だった。
スマン。
そういう意味ではないようだわ。
or eax,ebx
とかだと、直前までの命令でeaxとebxの両方のレジスタの値が決まってないと
パイプライン上でこの命令ALUのステージを実行することは出来ないので待機が
発生する。
ところが、xor eax,eax だと直前までの命令のeaxの結果がどうであれ、この
命令は必ずeaxを0にしてしまうから、待機する必要が無い、という意味だった。
916デフォルトの名無しさん
2020/11/26(木) 20:18:29.14ID:l8W6EZba コード長はくだらん揚げ足取りに見える。普通にオペランドも入れて解釈すべきでキャッシュ効率は不利。
昔からレジスタ初期化で多用されるxorは組み合わせ回路、ワイヤードロジック一発で多くのCPUでも特別扱い。
XOR r32, r32 L: 0.07ns= 0.2c T: 0.07ns= 0.24c
OR r32, r32 L: 0.29ns= 1.0c T: 0.07ns= 0.25c
AND r32, r32 L: 0.29ns= 1.0c T: 0.10ns= 0.33c
昔からレジスタ初期化で多用されるxorは組み合わせ回路、ワイヤードロジック一発で多くのCPUでも特別扱い。
XOR r32, r32 L: 0.07ns= 0.2c T: 0.07ns= 0.24c
OR r32, r32 L: 0.29ns= 1.0c T: 0.07ns= 0.25c
AND r32, r32 L: 0.29ns= 1.0c T: 0.10ns= 0.33c
917デフォルトの名無しさん
2020/11/26(木) 20:42:01.46ID:l8W6EZba よく使う命令を重点的にトランジスタを大量投入して速くしようというのはコードの互換性を大事にしてるからの発想。古いコードでも速く動かしてやるという努力の賜物のx86。
一方、使わない命令は削除、もう頭使うのが嫌だからと最適化はコンパイラの仕事と最適化を放り出して衰退したRISC哲学。
一方、使わない命令は削除、もう頭使うのが嫌だからと最適化はコンパイラの仕事と最適化を放り出して衰退したRISC哲学。
918デフォルトの名無しさん
2020/11/26(木) 20:43:40.28ID:lH6B10sG >>916
mov reg,0
は、オペランドも全て含めて2バイト。
0は、short formで8BITオペランドになるから。
xor reg,regは、immオペランドが無くても2バイト。
なぜなら、movは、特別な短いマシン語が割り当てられているのに、xorは
そうではないから。
mov reg,0
は、オペランドも全て含めて2バイト。
0は、short formで8BITオペランドになるから。
xor reg,regは、immオペランドが無くても2バイト。
なぜなら、movは、特別な短いマシン語が割り当てられているのに、xorは
そうではないから。
919デフォルトの名無しさん
2020/11/26(木) 20:50:33.32ID:weG7Hi1V タブ機能付きのソフト(AcrobatReaderとかテキストエディターとか)の現在アクティブな
タブのファイルパスのアドレスを調べたいんですけど、めちゃめちゃ頑張ったんですけど無理でした。
わかったことは、AcrobatReaderの場合、開いた順にインデックスが振られて(初めの値は0
ではなく1)、アクティブタブのインデックスが格納されたアドレスがあるということです。
もしくはインデックスが振られるのではなく、ファイルパスを開いた順に配列にプッシュして
ファイルパス配列[アクティブタブのインデックス - 1] のタブをアクティブにしろという命令が出てる。
前者の場合、インデックスが格納されてるアドレスがどこかさっぱりわかんなくって、ファイルパス
のアドレスからちょっと前をみたりマックスパスの260Byte後ろのとこを見たりしたんですけど
それらしきインデックスが見つかりませぬ。
それで、ファイルパスにアクセスしてる関数を見たんですけどアセンブリ言語サッパリ( 一一)
どなたか助言お願いします。
ファイルパスにアクセスしてるらしき関数↓
AcroRd32.dll+4637E - 33 D2 - xor edx,edx
AcroRd32.dll+46380 - 8B C1 - mov eax,ecx
AcroRd32.dll+46382 - 66 39 11 - cmp [ecx],dx
AcroRd32.dll+46385 - 74 08 - je AcroRd32.dll+4638F
AcroRd32.dll+46387 - 83 C0 02 - add eax,02 { 2 }
AcroRd32.dll+4638A - 66 39 10 - cmp [eax],dx
AcroRd32.dll+4638D - 75 F8 - jne AcroRd32.dll+46387
AcroRd32.dll+4638F - 2B C1 - sub eax,ecx
AcroRd32.dll+46391 - D1 F8 - sar eax,1
AcroRd32.dll+46393 - 5D - pop ebp
AcroRd32.dll+46394 - C3 - ret
もう1週間くらい頑張ってます。宜しくお願いします。
タブのファイルパスのアドレスを調べたいんですけど、めちゃめちゃ頑張ったんですけど無理でした。
わかったことは、AcrobatReaderの場合、開いた順にインデックスが振られて(初めの値は0
ではなく1)、アクティブタブのインデックスが格納されたアドレスがあるということです。
もしくはインデックスが振られるのではなく、ファイルパスを開いた順に配列にプッシュして
ファイルパス配列[アクティブタブのインデックス - 1] のタブをアクティブにしろという命令が出てる。
前者の場合、インデックスが格納されてるアドレスがどこかさっぱりわかんなくって、ファイルパス
のアドレスからちょっと前をみたりマックスパスの260Byte後ろのとこを見たりしたんですけど
それらしきインデックスが見つかりませぬ。
それで、ファイルパスにアクセスしてる関数を見たんですけどアセンブリ言語サッパリ( 一一)
どなたか助言お願いします。
ファイルパスにアクセスしてるらしき関数↓
AcroRd32.dll+4637E - 33 D2 - xor edx,edx
AcroRd32.dll+46380 - 8B C1 - mov eax,ecx
AcroRd32.dll+46382 - 66 39 11 - cmp [ecx],dx
AcroRd32.dll+46385 - 74 08 - je AcroRd32.dll+4638F
AcroRd32.dll+46387 - 83 C0 02 - add eax,02 { 2 }
AcroRd32.dll+4638A - 66 39 10 - cmp [eax],dx
AcroRd32.dll+4638D - 75 F8 - jne AcroRd32.dll+46387
AcroRd32.dll+4638F - 2B C1 - sub eax,ecx
AcroRd32.dll+46391 - D1 F8 - sar eax,1
AcroRd32.dll+46393 - 5D - pop ebp
AcroRd32.dll+46394 - C3 - ret
もう1週間くらい頑張ってます。宜しくお願いします。
920デフォルトの名無しさん
2020/11/27(金) 00:50:22.02ID:dazyxaWu >>918
ならないな。バイナリ出して。
0100 mov ax,0
0103 xor ax,ax
0100 B8 00 00 31 C0
B8 00 00 00 00 mov eax,0
33 C0 xor eax,eax
ならないな。バイナリ出して。
0100 mov ax,0
0103 xor ax,ax
0100 B8 00 00 31 C0
B8 00 00 00 00 mov eax,0
33 C0 xor eax,eax
921デフォルトの名無しさん
2020/11/27(金) 00:56:36.27ID:lOUpIwv2 OllyDbg などの逆アセンブラツールを使えないのか?
922デフォルトの名無しさん
2020/11/27(金) 14:37:53.57ID:35rurNSb >>919
何をしたいのかが分からないが、例えばVS2019にAcrobatReaderの*.exeファイルを
ドラッグアンドドロップして、デバッグを開始し、タブにファイルを開いた状態にする。
そこでデバッガによりアプリを停止させて、メモリー内でそのファイル名を検索する。
どうやって検索すればよいかは良く知らない。
VS2019ではなく、OllyDbgなどを使えばよいかもしれない。
それでファイル名が入っているメモリーアドレスは分かることは分かる。
もう一つは、ファイルをオープンする場合、必ず Win32 の CreateFile APIが呼び出される
ので、CreateFileの 関数アドレスにブレイクポイントを仕掛ける。
その状態で実行すると何回かブレイクしているうち、タブのファイル名に対して
CreateFileが呼び出されることがあるはず。
その状態になったら、コールスタック(呼び出し履歴)を辿って、CreateFileを
呼び出している場所を見つける。そうすると、ファイル名を渡しているコードが
見つかる。
何をしたいのかが分からないが、例えばVS2019にAcrobatReaderの*.exeファイルを
ドラッグアンドドロップして、デバッグを開始し、タブにファイルを開いた状態にする。
そこでデバッガによりアプリを停止させて、メモリー内でそのファイル名を検索する。
どうやって検索すればよいかは良く知らない。
VS2019ではなく、OllyDbgなどを使えばよいかもしれない。
それでファイル名が入っているメモリーアドレスは分かることは分かる。
もう一つは、ファイルをオープンする場合、必ず Win32 の CreateFile APIが呼び出される
ので、CreateFileの 関数アドレスにブレイクポイントを仕掛ける。
その状態で実行すると何回かブレイクしているうち、タブのファイル名に対して
CreateFileが呼び出されることがあるはず。
その状態になったら、コールスタック(呼び出し履歴)を辿って、CreateFileを
呼び出している場所を見つける。そうすると、ファイル名を渡しているコードが
見つかる。
923デフォルトの名無しさん
2020/11/27(金) 14:42:33.59ID:35rurNSb >>922
なお、ファイルパスの入っているアドレスは分かる様になるが、
当然、アドレスは毎回変化するので、果たして何をしたいか、ということになる。
ファイルパスを入れているメモリーブロックを malloc や new している
コードを探すことは出来るかもしれないし、そのアドレスをどこかに格納している
コードも探すことは可能かも知れない。
が、複雑すぎて、そこで得た知見で何かをするということは
アセンブラに最高に詳しい人でもかなり難しい。
なお、ファイルパスの入っているアドレスは分かる様になるが、
当然、アドレスは毎回変化するので、果たして何をしたいか、ということになる。
ファイルパスを入れているメモリーブロックを malloc や new している
コードを探すことは出来るかもしれないし、そのアドレスをどこかに格納している
コードも探すことは可能かも知れない。
が、複雑すぎて、そこで得た知見で何かをするということは
アセンブラに最高に詳しい人でもかなり難しい。
924デフォルトの名無しさん
2020/11/27(金) 14:47:20.40ID:35rurNSb >>923
例えば、OllyDbgなどを使えば、ファイルパスが入っているメモリーアドレスを
検索して探し出すことは出来るかも知れない。
それで見つかったアドレスを X とする。
今度は、そのアドレス X を格納しているメモリーを探すこともできることはできる
可能性がある。
その場合、little endian なので、バイトレベルでは下位バイトから上位バイトに
向かって格納されていることに注意する。
ただし、アドレスXが格納されているアドレスは、複数見つかる可能性がある。
また、X そのものではなく、X より少し小さいアドレスが格納されていることもありえる。
だから、このような解析は難しいものとなる。
またこのような方法以外に、dumpbin に /disasm オプションをつけて Acrobat の *.exeを
逆アセンブルした結果を併用するのが基本。
例えば、OllyDbgなどを使えば、ファイルパスが入っているメモリーアドレスを
検索して探し出すことは出来るかも知れない。
それで見つかったアドレスを X とする。
今度は、そのアドレス X を格納しているメモリーを探すこともできることはできる
可能性がある。
その場合、little endian なので、バイトレベルでは下位バイトから上位バイトに
向かって格納されていることに注意する。
ただし、アドレスXが格納されているアドレスは、複数見つかる可能性がある。
また、X そのものではなく、X より少し小さいアドレスが格納されていることもありえる。
だから、このような解析は難しいものとなる。
またこのような方法以外に、dumpbin に /disasm オプションをつけて Acrobat の *.exeを
逆アセンブルした結果を併用するのが基本。
925デフォルトの名無しさん
2020/11/27(金) 14:53:31.46ID:35rurNSb >>924
そのような方法で粘り強く解析していくと、dumpbinの逆アセンブルコードの
どのあたりで、ファイルパスを格納するメモリーを確保し、そのアドレスを
どこかに記録しているコードは見つかる可能性は有る。
ただし、問題はそう簡単ではなく、「どこかに記録している」の「どこか」
がまた、毎回アドレスが変わることにある。
C/C++で言えば、非常に多数の構造体が連鎖的にリンクされているから。
このくらいの規模のアプリだと、その連鎖は、10以上になることは少なくない。
連鎖の仕方もif分などで場合分けされていて、条件によって複雑に代わりうる。
ソースコードがあっても複雑すぎてなにをやっているかを理解することはとても
困難。だから、ソースコードが無い状態でそれを理解することはとてつもなく
難しい。
そのような方法で粘り強く解析していくと、dumpbinの逆アセンブルコードの
どのあたりで、ファイルパスを格納するメモリーを確保し、そのアドレスを
どこかに記録しているコードは見つかる可能性は有る。
ただし、問題はそう簡単ではなく、「どこかに記録している」の「どこか」
がまた、毎回アドレスが変わることにある。
C/C++で言えば、非常に多数の構造体が連鎖的にリンクされているから。
このくらいの規模のアプリだと、その連鎖は、10以上になることは少なくない。
連鎖の仕方もif分などで場合分けされていて、条件によって複雑に代わりうる。
ソースコードがあっても複雑すぎてなにをやっているかを理解することはとても
困難。だから、ソースコードが無い状態でそれを理解することはとてつもなく
難しい。
926デフォルトの名無しさん
2020/11/27(金) 19:42:52.50ID:ljdbT47c でも有能なハッカーはそれを解読するよね
927デフォルトの名無しさん
2020/11/27(金) 22:46:27.98ID:ULLAjR/s >>926
お前さんは有能なハッカーですか?
お前さんは有能なハッカーですか?
928デフォルトの名無しさん
2020/11/28(土) 00:05:40.76ID:OUdaBd4w >>926
ハッカーは、ハッキングに関係ないことは何もやらないでしょう
ハッカーは、ハッキングに関係ないことは何もやらないでしょう
929デフォルトの名無しさん
2020/11/28(土) 00:34:33.70ID:qjEapHwo > mov reg,0
> は、オペランドも全て含めて2バイト。
> 0は、short formで8BITオペランドになるから。
これって本当なの? そうアセンブルされないけど。
> は、オペランドも全て含めて2バイト。
> 0は、short formで8BITオペランドになるから。
これって本当なの? そうアセンブルされないけど。
930デフォルトの名無しさん
2020/11/28(土) 17:46:27.32ID:WIRcuTWz931デフォルトの名無しさん
2020/11/28(土) 20:17:09.98ID:qjEapHwo アスペなの? ボクのCPUの話じゃなく、
本人はz80ではなくx86だと言ってるからx86の話を聞いているんだよ。
他社の互換含めてx86系CPUが一体どれだけあると思ってるの? 全部確認できるわけないじゃん。
本人はz80ではなくx86だと言ってるからx86の話を聞いているんだよ。
他社の互換含めてx86系CPUが一体どれだけあると思ってるの? 全部確認できるわけないじゃん。
932デフォルトの名無しさん
2020/11/28(土) 20:21:31.70ID:kjtXSxRe >>919
です!!>>922 さんありがとうございました!
なんとアクティブタブのファイルパスアドレス見つかりました!
AHKですけど、よかったら皆さんこの関数使ってください!
;==================================================
JEE_GetAcroRd32Path(hWnd)
{
WinGetClass, vWinClass, % "ahk_id " hWnd
if !(vWinClass = "AcrobatSDIWindow")
return
WinGet, vPID, PID, % "ahk_id " hWnd
WinGet, vPPath, ProcessPath, % "ahk_id " hWnd
FileGetVersion, vPVersion, % vPPath
MAX_PATH := 260
;PROCESS_QUERY_INFORMATION := 0x400 ;PROCESS_VM_READ := 0x10
if !hProc := DllCall("kernel32\OpenProcess", UInt,0x410, Int,0, UInt,vPID, Ptr)
return
if !vAddress && A_Is64bitOS
{
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
vPIs64 := !vIsWow64Process
}
です!!>>922 さんありがとうございました!
なんとアクティブタブのファイルパスアドレス見つかりました!
AHKですけど、よかったら皆さんこの関数使ってください!
;==================================================
JEE_GetAcroRd32Path(hWnd)
{
WinGetClass, vWinClass, % "ahk_id " hWnd
if !(vWinClass = "AcrobatSDIWindow")
return
WinGet, vPID, PID, % "ahk_id " hWnd
WinGet, vPPath, ProcessPath, % "ahk_id " hWnd
FileGetVersion, vPVersion, % vPPath
MAX_PATH := 260
;PROCESS_QUERY_INFORMATION := 0x400 ;PROCESS_VM_READ := 0x10
if !hProc := DllCall("kernel32\OpenProcess", UInt,0x410, Int,0, UInt,vPID, Ptr)
return
if !vAddress && A_Is64bitOS
{
DllCall("kernel32\IsWow64Process", Ptr,hProc, IntP,vIsWow64Process)
vPIs64 := !vIsWow64Process
}
933デフォルトの名無しさん
2020/11/28(土) 20:22:46.29ID:Sl4N7Gov AMD64やIA-32eのマニュアルに2バイトで0クリア出来るオペコードはないように見えるな
934デフォルトの名無しさん
2020/11/28(土) 20:23:26.87ID:kjtXSxRe if !vAddress
{
VarSetCapacity(MEMORY_BASIC_INFORMATION, A_PtrSize=8?48:28, 0)
vAddress := 0
Loop
{
if !DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
break
vMbiBaseAddress := NumGet(MEMORY_BASIC_INFORMATION, 0, "Ptr")
vMbiRegionSize := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?24:12, "UPtr")
vMbiState := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?32:16, "UInt")
;vMbiProtect := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?36:20, "UInt")
vMbiType := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?40:24, "UInt")
vName := ""
if (vMbiState & 0x1000) ;MEM_COMMIT := 0x1000
&& (vMbiType & 0x1000000) ;MEM_IMAGE := 0x1000000
;&& (vMbiProtect = 0x4) ;PAGE_READWRITE := 0x4
{
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if !(vPath = "")
SplitPath, vPath, vName
}
{
VarSetCapacity(MEMORY_BASIC_INFORMATION, A_PtrSize=8?48:28, 0)
vAddress := 0
Loop
{
if !DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
break
vMbiBaseAddress := NumGet(MEMORY_BASIC_INFORMATION, 0, "Ptr")
vMbiRegionSize := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?24:12, "UPtr")
vMbiState := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?32:16, "UInt")
;vMbiProtect := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?36:20, "UInt")
vMbiType := NumGet(MEMORY_BASIC_INFORMATION, A_PtrSize=8?40:24, "UInt")
vName := ""
if (vMbiState & 0x1000) ;MEM_COMMIT := 0x1000
&& (vMbiType & 0x1000000) ;MEM_IMAGE := 0x1000000
;&& (vMbiProtect = 0x4) ;PAGE_READWRITE := 0x4
{
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if !(vPath = "")
SplitPath, vPath, vName
}
935デフォルトの名無しさん
2020/11/28(土) 20:25:32.47ID:kjtXSxRe if InStr(vName, "AcroRd32.dll")
{
;get address where path starts
;if vPIs64{
; vAddress := vMbiBaseAddress + 0x19d3d9c
;}
;else{
vAddress := vMbiBaseAddress + 0x19d3d9c
;}
break
}
vAddress += vMbiRegionSize
if 0
if (vAddress > 2**32-1) ;4 gigabytes
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
}
}
{
;get address where path starts
;if vPIs64{
; vAddress := vMbiBaseAddress + 0x19d3d9c
;}
;else{
vAddress := vMbiBaseAddress + 0x19d3d9c
;}
break
}
vAddress += vMbiRegionSize
if 0
if (vAddress > 2**32-1) ;4 gigabytes
{
DllCall("kernel32\CloseHandle", Ptr,hProc)
return
}
}
}
936デフォルトの名無しさん
2020/11/28(土) 20:26:33.51ID:kjtXSxRe VarSetCapacity(MEMORY_BASIC_INFORMATION, A_PtrSize=8?48:28, 0)
if vAddress
&& DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vMbiBaseAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
{
memVal := ReadMemory32(vAddress, 0, vPID)
memVal := ReadMemory32(memVal, 0x78, vPID)
memVal := ReadMemory32(memVal, 0x18, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
;memVal += 0x0
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if InStr(vPath, "AcroRd32.dll")
{
vPath2 := ""
VarSetCapacity(vPath2, MAX_PATH*2, 0)
DllCall("ReadProcessMemory", "UInt", hProc, UInt, memVal, Str, vPath2, Uint, MAX_PATH*2, UPtr,0)
vPath3 := StrGet(&vPath2, "cp932")
}
}
DllCall("kernel32\CloseHandle", Ptr, hProc)
return vPath3
}
if vAddress
&& DllCall("kernel32\VirtualQueryEx", Ptr,hProc, Ptr,vMbiBaseAddress, Ptr,&MEMORY_BASIC_INFORMATION, UPtr,A_PtrSize=8?48:28, UPtr)
{
memVal := ReadMemory32(vAddress, 0, vPID)
memVal := ReadMemory32(memVal, 0x78, vPID)
memVal := ReadMemory32(memVal, 0x18, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
memVal := ReadMemory32(memVal, 0x10, vPID)
;memVal += 0x0
vPath := ""
VarSetCapacity(vPath, MAX_PATH*2)
DllCall("psapi\GetMappedFileName", Ptr,hProc, Ptr,vMbiBaseAddress, Str,vPath, UInt,MAX_PATH*2, UInt)
if InStr(vPath, "AcroRd32.dll")
{
vPath2 := ""
VarSetCapacity(vPath2, MAX_PATH*2, 0)
DllCall("ReadProcessMemory", "UInt", hProc, UInt, memVal, Str, vPath2, Uint, MAX_PATH*2, UPtr,0)
vPath3 := StrGet(&vPath2, "cp932")
}
}
DllCall("kernel32\CloseHandle", Ptr, hProc)
return vPath3
}
937デフォルトの名無しさん
2020/11/28(土) 20:28:28.40ID:kjtXSxRe ReadMemory32(MADDRESS, pOffset = 0, activePID := 0)
{
VarSetCapacity(MVALUE,8)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", activePID, "UInt")
lastErr := DllCall("GetLastError")
DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS+pOffset, "Str", MVALUE, "Uint",8, "Uint *",0)
DllCall("CloseHandle", "int", ProcessHandle)
result := 0
Loop 4{
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
}
return result
}
{
VarSetCapacity(MVALUE,8)
ProcessHandle := DllCall("OpenProcess", "Int", 24, "Char", 0, "UInt", activePID, "UInt")
lastErr := DllCall("GetLastError")
DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", MADDRESS+pOffset, "Str", MVALUE, "Uint",8, "Uint *",0)
DllCall("CloseHandle", "int", ProcessHandle)
result := 0
Loop 4{
result += *(&MVALUE + A_Index-1) << 8*(A_Index-1)
}
return result
}
938デフォルトの名無しさん
2020/11/29(日) 13:50:46.99ID:tmDS9Mir939デフォルトの名無しさん
2020/11/29(日) 13:51:20.22ID:tmDS9Mir AutoHotKeyか。
940デフォルトの名無しさん
2020/11/29(日) 15:27:25.94ID:g07v1NN9941デフォルトの名無しさん
2020/11/29(日) 15:41:01.10ID:tmDS9Mir942デフォルトの名無しさん
2020/11/29(日) 15:50:37.08ID:sV/hNKwx x86で該当しそうなのはmovzx movsxくらいだけどな。
movzx ax,0
でオペランド含めて
OF B6 00
の3バイト。
xor ax,axが1バイトというのはオペランドを含まないならそうかもしれんな。
mov ax,0がオペランド込みで2バイトのコードがあるなら教えてほしい。
movzx ax,0
でオペランド含めて
OF B6 00
の3バイト。
xor ax,axが1バイトというのはオペランドを含まないならそうかもしれんな。
mov ax,0がオペランド込みで2バイトのコードがあるなら教えてほしい。
943デフォルトの名無しさん
2020/11/29(日) 16:30:48.26ID:tmDS9Mir >>942
8BIT測値を16/32BITに拡張する「即値拡張」なる形式が、add,sub,or,xor,and
adc,sbb,cmp や、push,imul には存在しているが、mov命令には存在してないようだ。
8BIT測値を16/32BITに拡張する「即値拡張」なる形式が、add,sub,or,xor,and
adc,sbb,cmp や、push,imul には存在しているが、mov命令には存在してないようだ。
944デフォルトの名無しさん
2020/11/29(日) 19:36:03.18ID:g07v1NN9 >>941
AcrobatReaderのウィンドウハンドルを渡して、アクティブタブのファイルパス
が返ってくる関数ですよー。
F1::
;F1を押したら
;アクティブウィンドウハンドルの取得(AcrobatReaderをアクティブにしといてください)
hwnd := WinExist("A")
;アクティブタブのファイルパスを取得
filePath := JEE_GetAcroRd32Path(hwnd)
;メッセージボックスで表示
MsgBox, % filePath
return
こんな感じで使ってください。
AcrobatReaderのウィンドウハンドルを渡して、アクティブタブのファイルパス
が返ってくる関数ですよー。
F1::
;F1を押したら
;アクティブウィンドウハンドルの取得(AcrobatReaderをアクティブにしといてください)
hwnd := WinExist("A")
;アクティブタブのファイルパスを取得
filePath := JEE_GetAcroRd32Path(hwnd)
;メッセージボックスで表示
MsgBox, % filePath
return
こんな感じで使ってください。
945デフォルトの名無しさん
2020/11/30(月) 06:36:20.46ID:jVClAyvr ここそういうスレだっけ?
946デフォルトの名無しさん
2020/11/30(月) 15:37:02.85ID:SYaCp1kg スレチすまそ
947デフォルトの名無しさん
2020/11/30(月) 21:26:57.27ID:aenc2Jvq どうせ過疎ってんだからいいだろ
948デフォルトの名無しさん
2020/12/01(火) 01:21:53.10ID:QGlkeoFk え?なんで?
949デフォルトの名無しさん
2020/12/01(火) 14:57:54.27ID:hTz4hSGC 誰も何も書かなきゃ落ちるから
950デフォルトの名無しさん
2020/12/01(火) 15:06:31.69ID:5apuVehD それでも関係ないこと書くのは違うな
951デフォルトの名無しさん
2020/12/01(火) 15:45:01.61ID:hTz4hSGC じゃあきみが頑張って書いてスレを維持してくれ
952デフォルトの名無しさん
2020/12/01(火) 20:53:32.04ID:QGlkeoFk 人がいないスレをわざわざ上げる必要ないので
関係ない話なら他の上がっているスレに書けばいいだろ
関係ない話なら他の上がっているスレに書けばいいだろ
953デフォルトの名無しさん
2020/12/12(土) 05:38:07.46ID:0YPrQOFp ほしゆ(・ω・)
954デフォルトの名無しさん
2020/12/12(土) 17:19:41.14ID:YnqZkJbK あーあ、誰も書かなくなったw 落ちるぞ
955デフォルトの名無しさん
2020/12/13(日) 02:46:51.94ID:46vi4xSP 素朴な思い付きの疑問なのだけど、どうして書籍としてAMD64の入門書が無いの?
需要も知識ある人も、それなりに居そうだけど。
まさか、AMDから許可がおりないとか?
需要も知識ある人も、それなりに居そうだけど。
まさか、AMDから許可がおりないとか?
956デフォルトの名無しさん
2020/12/13(日) 06:59:00.79ID:5t0HrIYx ほしゆ(・ω・)
957デフォルトの名無しさん
2020/12/13(日) 15:57:52.04ID:+kVWWkIy >>955
書けば売れるんじゃね
書けば売れるんじゃね
958デフォルトの名無しさん
2020/12/13(日) 17:46:48.41ID:tEItIdi/ >>955
「図解64ビットがわかる (図解 知りたい!テクノロジー)」でググれ
「図解64ビットがわかる (図解 知りたい!テクノロジー)」でググれ
959955
2020/12/14(月) 05:46:00.53ID:lPWXZq4e960デフォルトの名無しさん
2020/12/14(月) 09:33:35.43ID:7ZAWu3kI >>958
この人の本ってプログラミングに役立つん?
この人の本ってプログラミングに役立つん?
961デフォルトの名無しさん
2020/12/14(月) 15:32:42.23ID:7+Opk3xu 普通に考えてAMDやIntelが公開している最適化マニュアル等の方が役立つ
962デフォルトの名無しさん
2020/12/14(月) 17:48:08.53ID:yiGrKys0963デフォルトの名無しさん
2020/12/15(火) 23:33:29.39ID:JKngFzP4 64bitアセンブラの本もあるじゃないか
「64ビットアセンブラ入門―64ビットCPUの基本構造もやさしく解説」 (Amazon)
「64ビットアセンブラ入門―64ビットCPUの基本構造もやさしく解説」 (Amazon)
964デフォルトの名無しさん
2020/12/16(水) 08:28:24.95ID:4AurUS4h アセンブラは、C のポインタで躓かないように
Z80 程度を少し (もちろんポインタを使う程度) やればいいと思う。
Z80 程度を少し (もちろんポインタを使う程度) やればいいと思う。
965デフォルトの名無しさん
2020/12/16(水) 11:53:24.15ID:2Jfp/ir2 アセンブラやるのにアーキテクチャやCが必要なのかな?
966デフォルトの名無しさん
2020/12/16(水) 19:53:44.68ID:xpVb4SZu >>965
各種レジスタ構成やそれらの性質、仮想記憶のしくみなどを知らずにアセンブラやろうとするのは無謀もいいとこだろう。
Cで書いたコードの一部をアセンブラに書き換えて変更したり最適化するとき、Cのコードに対応するアセンブラソースが
どうなっているか見るにはCで何をしようとしているかわからないと話にならないだろう。
こういうことは知ってて損することはない。
各種レジスタ構成やそれらの性質、仮想記憶のしくみなどを知らずにアセンブラやろうとするのは無謀もいいとこだろう。
Cで書いたコードの一部をアセンブラに書き換えて変更したり最適化するとき、Cのコードに対応するアセンブラソースが
どうなっているか見るにはCで何をしようとしているかわからないと話にならないだろう。
こういうことは知ってて損することはない。
967デフォルトの名無しさん
2020/12/19(土) 08:32:12.96ID:SL5FUo+H >>963
その本、Cから呼び出す前提だったから、アセンブラでの変数宣言の仕方は載ってない。
その本、Cから呼び出す前提だったから、アセンブラでの変数宣言の仕方は載ってない。
968デフォルトの名無しさん
2020/12/19(土) 19:14:03.47ID:wFrehAp+969デフォルトの名無しさん
2020/12/19(土) 20:11:53.26ID:TfP5rB1Q CD21 を学習しないとなw
970デフォルトの名無しさん
2020/12/19(土) 21:14:42.16ID:61b7WmYd Cが先か?アセンブラが先か?
971デフォルトの名無しさん
2020/12/20(日) 04:41:50.25ID:mOcnJILL >>970
Cコンパイラが生成したアセンブラよく読んだよ
Cコンパイラが生成したアセンブラよく読んだよ
972デフォルトの名無しさん
2020/12/20(日) 12:47:01.51ID:NmAfNXJq >>967
int some_data = 5;
という変数は、アセンブラでは以下のようにすると定義できる:
_DATA segment DWORD
_some_data dd 5
_DATA ends
dd は、define dword の意味。db だと byte, dw だと word、となる。
構造体の場合は、struc を使うか、または、メンバのdd,dw,dbをそのまま並べる。
自動 align はされないので、alignment をとりたい場合は、自分で pading するか、
align 擬似命令か、even 擬似命令を使う。
int some_data = 5;
という変数は、アセンブラでは以下のようにすると定義できる:
_DATA segment DWORD
_some_data dd 5
_DATA ends
dd は、define dword の意味。db だと byte, dw だと word、となる。
構造体の場合は、struc を使うか、または、メンバのdd,dw,dbをそのまま並べる。
自動 align はされないので、alignment をとりたい場合は、自分で pading するか、
align 擬似命令か、even 擬似命令を使う。
973デフォルトの名無しさん
2020/12/20(日) 12:48:36.41ID:NmAfNXJq _DATA segment DWORD
の部分の DWORD は、そのセグメントの先頭を、DWORD でアラインする、という
意味。つまり、セグメントの先頭アドレスが 4 の倍数に配置される。
省略も可能。
アラインメントをしなくてもプログラムは動くが、少し遅くなることが有る。
の部分の DWORD は、そのセグメントの先頭を、DWORD でアラインする、という
意味。つまり、セグメントの先頭アドレスが 4 の倍数に配置される。
省略も可能。
アラインメントをしなくてもプログラムは動くが、少し遅くなることが有る。
974デフォルトの名無しさん
2020/12/21(月) 08:58:26.80ID:LKkS73pR >>973
いやいや、bus errorでしょもう。
いやいや、bus errorでしょもう。
975デフォルトの名無しさん
2020/12/21(月) 11:00:51.03ID:i3HSzHFO 今時のISAはアライメントズレでロード/ストアした場合でも遅くなるだけじゃね
IA32、AMD64、ARM、RX、RISC-V
あたりはアライメントがずれていても例外は吐かないように見える
IA32、AMD64、ARM、RX、RISC-V
あたりはアライメントがずれていても例外は吐かないように見える
976デフォルトの名無しさん
2020/12/21(月) 13:34:54.19ID:xeeueWnS977デフォルトの名無しさん
2020/12/21(月) 13:38:38.63ID:xeeueWnS 構造体メンバのアラインメントも、x86, AMD64 では速度面以外では必要ではない。
他の系統のCPUでは、アラインメントが揃ってないと読み込めない様になっている
ことがあるが、x86, AMD64 の人から見ると、そういったCPUに足をひきづられて
ウザイことがある。
そういうCPUのために、x86, x64 では不要の構造体のアラインメントなどウルサすぎる。
他の系統のCPUでは、アラインメントが揃ってないと読み込めない様になっている
ことがあるが、x86, AMD64 の人から見ると、そういったCPUに足をひきづられて
ウザイことがある。
そういうCPUのために、x86, x64 では不要の構造体のアラインメントなどウルサすぎる。
978デフォルトの名無しさん
2020/12/21(月) 14:24:05.05ID:xeeueWnS 構造体メンバのアラインは、x86、x64でも速度のために有ったほうが良いかも
知れないが、バイナリファイルの中の32BIT整数の部分をアラインするのは、
ちょっと抵抗を感じることがある。
ファイルの場合、読み込み速度よりサイズの小ささが重要だと思うので。
他のCPUでは読み込めないなら、そのCPUの設計が欠陥だとも考えられるし、
そんなCPUの事まで配慮してサイズが増大するのはいい迷惑。
知れないが、バイナリファイルの中の32BIT整数の部分をアラインするのは、
ちょっと抵抗を感じることがある。
ファイルの場合、読み込み速度よりサイズの小ささが重要だと思うので。
他のCPUでは読み込めないなら、そのCPUの設計が欠陥だとも考えられるし、
そんなCPUの事まで配慮してサイズが増大するのはいい迷惑。
979デフォルトの名無しさん
2020/12/21(月) 17:07:46.38ID:GZaqA6YK バイナリファイル解析してるとアライン考慮部分と全く配慮してないが混在されてるのがまれによくある
980デフォルトの名無しさん
2020/12/21(月) 19:28:27.84ID:LKkS73pR アライメントなんかアセンブルディレクティブ疑似命令で自動でやってくれるでしょ.sizeofとかもアライメント考慮してサイズ返してくれるし。
コンパイラが再生するデータ構造はアライメント合わせされてる。x86でオプティマイズサイズだとされないか。
コンパイラが再生するデータ構造はアライメント合わせされてる。x86でオプティマイズサイズだとされないか。
981デフォルトの名無しさん
2020/12/21(月) 20:01:53.70ID:Ttyv2kNo 高性能PC!!
を謳ってる配信でintelが全く見当たらなくなったのは隔世の感があるな。
配信してる超絶プログラマさんももうAMDしか選択肢がない言うてた
を謳ってる配信でintelが全く見当たらなくなったのは隔世の感があるな。
配信してる超絶プログラマさんももうAMDしか選択肢がない言うてた
982デフォルトの名無しさん
2020/12/22(火) 00:21:52.28ID:tgdJRQi2 IA64やらずに超絶とは
983デフォルトの名無しさん
2020/12/22(火) 00:42:43.81ID:btWe0I+s IA64はお亡くなりになられたよ・・・
984デフォルトの名無しさん
2020/12/22(火) 11:00:09.36ID:kzqT97dS PS5はAMDなんだな
985デフォルトの名無しさん
2020/12/30(水) 01:28:02.70ID:ojaVEyJL ほしゆ(・ω・)
986デフォルトの名無しさん
2020/12/31(木) 08:09:56.84ID:qAEGulJg >>979
まれにあるのか?よくあることなのか?どっちでもいいが
まれにあるのか?よくあることなのか?どっちでもいいが
987デフォルトの名無しさん
2020/12/31(木) 12:53:32.07ID:pMMrEBim >>986
掲示板初心者か?
掲示板初心者か?
988デフォルトの名無しさん
2021/01/01(金) 08:45:04.14ID:ZYHKNI/v ・
989デフォルトの名無しさん
2021/01/01(金) 09:25:56.97ID:Sutdgdij 初心者スレで上級者気取りか?
990デフォルトの名無しさん
2021/01/01(金) 18:12:38.86ID:ADEdjdIz ・
991デフォルトの名無しさん
2021/01/01(金) 19:03:44.66ID:sqmHJxPF ほしゆ(・ω・)
992デフォルトの名無しさん
2021/01/01(金) 20:06:32.68ID:9XtueUbf いやもう次立てる所やろ
993デフォルトの名無しさん
2021/01/02(土) 07:31:18.88ID:wg370Djj ・
994デフォルトの名無しさん
2021/01/02(土) 18:03:52.31ID:kSzgq5SE ・
995デフォルトの名無しさん
2021/01/03(日) 06:33:21.26ID:qiwWktFe ・
996デフォルトの名無しさん
2021/01/03(日) 18:36:17.00ID:GJkrCLRp まもなくここは 乂1000取り合戦場乂 となります。
\∧_ヘ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
,,、,、,,, / \〇ノゝ∩ < 1000取り合戦、いくぞゴルァ!! ,,、,、,,,
/三√ ゚Д゚) / \____________ ,,、,、,,,
/三/| ゚U゚|\ ,,、,、,,, ,,、,、,,,
,,、,、,,, U (:::::::::::) ,,、,、,,, \オーーーーーーーッ!!/
//三/|三|\ ∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧
∪ ∪ ( ) ( ) ( ) )
,,、,、,,, ,,、,、,,, ∧_∧∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧
,,、,、,,, ( ) ( ) ( ) ( )
\∧_ヘ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
,,、,、,,, / \〇ノゝ∩ < 1000取り合戦、いくぞゴルァ!! ,,、,、,,,
/三√ ゚Д゚) / \____________ ,,、,、,,,
/三/| ゚U゚|\ ,,、,、,,, ,,、,、,,,
,,、,、,,, U (:::::::::::) ,,、,、,,, \オーーーーーーーッ!!/
//三/|三|\ ∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧
∪ ∪ ( ) ( ) ( ) )
,,、,、,,, ,,、,、,,, ∧_∧∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧
,,、,、,,, ( ) ( ) ( ) ( )
997デフォルトの名無しさん
2021/01/04(月) 06:34:03.38ID:se2ZF3ue ・
998デフォルトの名無しさん
2021/01/04(月) 17:11:09.20ID:4XmqFvVy ・
999デフォルトの名無しさん
2021/01/04(月) 17:11:25.37ID:4XmqFvVy ・
1000デフォルトの名無しさん
2021/01/04(月) 17:11:46.52ID:4XmqFvVy --- 終了 ---
10011001
Over 1000Thread このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 1361日 23時間 35分 51秒
新しいスレッドを立ててください。
life time: 1361日 23時間 35分 51秒
10021002
Over 1000Thread 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php
レス数が1000を超えています。これ以上書き込みはできません。
ニュース
- 「もうキモくてキモくて…」29歳女性が語る“おぢアタック”の実態。「俺ならイケるかも」年下女性を狙う勘違い中年男性に共通点が★4 [Hitzeschleier★]
- ミス・ユニバース フィンランド代表の「つり目」写真が波紋… 本人釈明も批判やまず 協会謝罪「徹底的に検証」へ [冬月記者★]
- 【おこめ券】鈴木憲和農相 小泉前農相の備蓄米放出を“反省”「備蓄の円滑な運営を図ってまいります」 [Hitzeschleier★]
- 自民・麻生太郎副総裁 石破政権の1年は「どよーん」 高市政権発足で「何となく明るくなった」「世の中のことが決まり動いている」★2 [Hitzeschleier★]
- 1人3千円の食品高騰対策、何に使える? あいまいなまま衆院通過 [蚤の市★]
- ゆたぼん 二重手術を報告「めちゃくちゃ気に入っています」 [muffin★]
- ネトウヨ、「高市さんがカンペを無視して存立危機発言をしたのは、岡田に『カンペ読むな』と執拗に言われたので言っただけ」と歴史を捏造 [314039747]
- コウメ太夫のネタ考えたから評価してくれ
- トランプ、G7に代わるcore 5を発表 [805596214]
- 【悲報】新米、全く売れなくて倉庫が満杯になってしまうwwwwwwwwwwwwwwwwwwww [802034645]
- 敵「ククク、キミの親友の俺くんの死体を蘇らせて操り、お前らと戦わせるぞ」お前ら「」←どうする?
- 【悲報】日本共産党、ツイッター速報にブチギレ法的措置WWWWWWWWWWWWWWWWWWWWWWWWWWWW [935793931]
