初心者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
■ このスレッドは過去ログ倉庫に格納されています
2017/04/13(木) 17:35:55.70ID:1WMn3pSz
123デフォルトの名無しさん
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
>目標はウイルスのデバッグとか出来るようになりたいです
どうしてそう反社会的な方ばっかり目がいくんだい。
これだから、ハッカー=クラッカー、悪者、のイメージが付く。
昔は、アセンブラといえば、速さのために学んだものなのに。
君みたいなのにはプログラムになんか興味を持たないで欲しい。
>目標はウイルスのデバッグとか出来るようになりたいです
どうしてそう反社会的な方ばっかり目がいくんだい。
これだから、ハッカー=クラッカー、悪者、のイメージが付く。
昔は、アセンブラといえば、速さのために学んだものなのに。
君みたいなのにはプログラムになんか興味を持たないで欲しい。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 「おこめ券は米以外の食品も買える。効果的な活用を」 地元で農水相 [山形県] [少考さん★]
- 高市首相の答弁書に「台湾有事答えない」と明記 存立危機発言当時 ★11 [蚤の市★]
- 【速報】「女芸人No.1決定戦 THE W」9代目女王にニッチェ! 7年ぶり3度目で悲願の優勝 [牛丼★]
- 【芸能】『女芸人No.1決定戦THE W』 粗品が最後にバッサリ「優勝賞金1000万円にしてはレベル低い大会」 [冬月記者★]
- 【沖縄】開業4ヵ月でこれは…“国民の税金”投入の『ジャングリア沖縄』で見た衝撃的な光景と、モチベーションが低い一部スタッフの現状 [ぐれ★]
- 【東京】「家族で話題にして」 “世田谷一家殺害から25年 警視庁が呼びかけ [煮卵★]
- クズ「勉強頑張らなかった奴は一生DQNと一緒に肉体労働しろ」☚勉強頑張れるのも環境と巡り合わせなんだが? [783475554]
- 俺の口癖が「へー」「そう」「どうも」なんだが
- 【時事】立憲民主党、30代の支持率が「ゼロ」😨 [369521721]
- うふ~ん♥死にたいわ~ん♥
- 加藤純一です
- 【正論】検察「山上よ、どんな事情があろうと暴力が許されない」 [442080748]
