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

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

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

関連スレ
アセンブラ 13
http://echo.2ch.net/test/read.cgi/tech/1314512680/
2018/08/22(水) 04:40:24.11ID:8qwUBnhH
補足:
/largeaddressaware:noを付けると64bitアプリでもメモリは2GBまでしか使えなくなる
2018/08/22(水) 04:46:45.21ID:8qwUBnhH
つまり、>>128が示してることは

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]
>のような書き方はしてはいけないということ
今までなんで絶対アドレスが出てくるのか疑問だったけど、コンパイラはこういうコードは吐かない、ってことだよね。
2018/08/22(水) 19:32:17.75ID:J61dDDqI
>>131

>>124 XvleiWNbとは別人だよね?

別人。ARMは使ったこと無い。
2018/08/22(水) 19:39:47.75ID:J61dDDqI
>>130
でも現実は、複雑。

なぜなら、COFFの仕様的には、obj ではない Image(EXEやDLLの事) のためだけに
ある .reloc section には、64BIT 絶対アドレスの再配置も行えるようになっているから。

現状の MS 製の link.exe がどうなっているかはともかく。
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 絶対アドレスに対応していても、無理だった。

勘違いした。
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 位の値だった。
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.
2018/08/22(水) 20:11:19.88ID:J61dDDqI
>>128
自分の勘だと、そのアドレスは、WinMain よりも、DLL の DllMain が置かれるような
値になってるね。

不思議だ。WinMain をそんな大きなアドレスに置く必要性は余り無いハズなので。
初期化データが 2GB 未満に置かれていても、malloc() や、new で確保されるデータは、
64BIT アドレスにできるはずだし。なお、

1_3f29_1770

↑は、32BIT を超えて、33BIT の値だな・・・。なんちゅう大きな値だろう。
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]
みたいなコードが例外吐いて特定困難なバグが発生するのを防止してるのでは?
140デフォルトの名無しさん
垢版 |
2018/08/22(水) 21:24:18.64ID:WDZbf6Te
例外吐くことで
2018/08/23(木) 05:44:12.90ID:sOVf8lyT
>>135
コマンドライン用の簡単なC言語の64bitのプログラムで試したが
main関数のアドレス=0x000000013f7f1000
data sectionで定義した変数data01のアドレス=0x000000013f7fc087
だったぞ
完全に32bit絶対アドレスの範囲を超えてる
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
2018/08/23(木) 07:09:02.23ID:4LRopBJn
>>139
>64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、
>mov   al,my_mojiretu[rbx]
>みたいなコードが例外吐いて特定困難なバグが発生するのを防止してるのでは?

意味不明だ。別に、
mov   al,my_mojiretu[rbx]
というコードが悪いわけではない。

むしろ、最適化のためには使った方が効率が良くなる。
2018/08/23(木) 07:22:22.74ID:4LRopBJn
>>141-142
もしそうだとすると、VC++ の吐くコードがx64の命令を上手く使いきれてないという事になる。
本来であれば、アドレスの配置を上手く行うだけで、64BIT モードでも特に問題なく
mov   al,my_mojiretu[rbx]
という命令は使えて、かつ、64BIT アドレスの制限を受けるわけでもないのだから。

ちなみに、アプリの EXE は、リンク後は固定アドレスで、ローダーがアドレスを再配置
する事はない。だから、ImageBase を小さい値になるようにリンクしさえすれば、
問題が生じない。
2018/08/23(木) 07:27:31.64ID:4LRopBJn
>>139
>64bitでイメージベースが大きくなったのは、セキュリティ関係でランダマイズしたりとか、

通常、コンピュータソフト、特にOSのセキュリティーというのは、そういう人間的なもの
ではなくて、もっと厳密な物だ。

ランダマイズして撹乱して相手の目をくらます、などという方法は通常取られない。

実際、EXE ファイルを解析した経験からしても、ランダマイズなどは全く行われていない。
何回リンクしても、同じアセンブリソースや、同じC++ソースなら、全く同じアドレスになる。
異なるソースであっても、ベースアドレスなどは、ほとんどの場合、固定値。
2018/08/23(木) 07:58:52.05ID:4LRopBJn
>>138
実際には問題がある。なぜなら、そんなにアドレスが大きいと、さっきから話題の
mov   al, my_mojiretu[rbx]
という命令が使えなくなるからだ。

これは、グローバルな配列変数を、添え字でアクセスするような場合に良いコードに
なる事がある。僅かではあるが。もし、この命令が使えないとなると、

mov   rdx,offset my_mojiretu
mov   al,[rdx + rbx]

のように、2つの命令を使わなくてはならなくなり、最適化上、不利になる。
2018/08/23(木) 08:10:29.27ID:wxGNRrqx
そんな事言い出したら
4GBや64KBに限定した方が小さいコードになるから
compactモデルにしよう
とかいう話にもなる

昔に戻りたい?
何のための64bit?
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 などにも
全て影響する貴重な間接オペランド。
2018/08/23(木) 08:46:40.08ID:4LRopBJn
>>147
8086時代の 64KB では制限が大きすぎて、ほとんどのプログラムで、制限が足かせ
になっていたので、32BIT になって、アドレスが 4GB に拡張されて非常に便利になった。

ところが、64BIT 時代になっても、そのときのようなメリットが無いと思うんだ。
AMD vs Intel の競争の結果出てきた産物かも知れない。そういうの、時々ある。
2018/08/23(木) 08:56:25.66ID:K9a3gVgQ
>>145
WindowsではASLRでランダム化普通にやってるらしいですよ

http://07c00.hatenablog.com/entry/2013/08/07/033443
OSがプロセスをロードするときに、ランダムな場所にモジュールを配置するセキュリティ機能です。
実際はモジュールだけじゃなく、スタックやヒープなどもランダマイズされたりします。
2018/08/23(木) 09:03:22.89ID:4LRopBJn
>>150
少なくとも、EXE の .text, .data セクションは再配置される事は無いはず。
なぜなら、.reloc section が存在せず、再配置する事が原理的に出来なくなっているから。

DLL は、.reloc section が残されているので再配置できる。ただし、再配置しなくても、
全てのシステムのDLLは、最初からアドレスが重ならないような ImageBase になっている
ので、再配置されずにそのままおかれるのが、昔は基本であった。
2018/08/23(木) 10:25:25.69ID:3bgfj1QZ
>>148
64bitコードで絶対番地に依存したコードとか
考え方が古いねえ

ていうか、
イヤなら2GB限定のコードにすればいい
コードもデータも2GBの範囲に割り当てられるから
2018/08/23(木) 11:01:43.32ID:4LRopBJn
>>152
じゃあなんで、MS純正VSは、いまだに 32BIT コードで動いてるのさ。

x64 は、レジスタが増えた事と、memmove() などが多分、倍の速度で動く事が
最大のメリットじゃないの?

アドレス幅が64BITになって現実的なメリットはどこにあるのかな?
2018/08/23(木) 11:36:32.13ID:3bgfj1QZ
なにが「じゃあ」だか

メリットが無いと思うなら2GB限定のアプリにすれば良い
って書いたのが見えなかった?
2018/08/23(木) 12:51:14.26ID:4LRopBJn
>>154
だから、メリットはあるよ。
レジスタが増えること、AVX, AVX2, AVX512 で、YMM, ZMM レジスタでベクトル
の次元が大きくなったSIMD 命令が使えること、3オペランドの以上のSIMD命令が使える
事、メモリ転送の速度が倍近くになること。malloc(), new が、2GB を超えて行える事。

初期化サイズが2GBを越えるメリットは余り無いと思ってるけど。
2018/08/23(木) 17:09:15.42ID:NMfUyUL+
>>149
アドレス空間は広いほうがいいに決まっている
ユーザーアドレス空間の断片化は基本防止できない、だったら入れものが広いほういい
2018/08/23(木) 17:09:45.22ID:NMfUyUL+
>>153
>>156
2018/08/23(木) 18:36:50.55ID:wxGNRrqx
>>155
2G限定と関係ないじゃん
2018/08/23(木) 19:03:15.16ID:sOVf8lyT
>>148
結局、
mov   al,my_mojiretu[rbx]
こんなコードを書くと64bitではLINKする時にエラーが出る
/largeaddressaware:noを指定するとLINKでエラーは出なくなるが、
/largeaddressaware:noを指定すると動的メモリも含め2GB以下のメモリしか扱えなくなる
2018/08/23(木) 19:09:33.40ID:QrjyoFcH
なんかしらあるんじゃね
2018/08/23(木) 19:30:53.52ID:k97Awv43
>>159
それでいいじゃん
何種類作るつもりだよ
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
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には対応しておりません。
2018/08/23(木) 20:04:05.41ID:k97Awv43
>>162
いや、
32bit/64bitアプリの話じゃなくて
64bitの2GB制限/制限なしアプリの話
2018/08/23(木) 20:05:15.44ID:sOVf8lyT
>>153
10年位前に出来たオンラインゲームでも、今はもう2GBのメモリだともう足りなくて
32bitのゲームでも/LARGEADDRESSAWAREのフラグ立てて延命してるのもあるよ
64bit WindowsならLAAフラグを立てると32bitアプリでも4GBまで使えるようになる
LAAで延命してるゲームで32bit Windowsで遊ぶとメモリ不足で高確率で落ちるゲームとか既にある
2018/08/23(木) 20:12:15.30ID:sOVf8lyT
こんな記事が出るくらい、2GBではメモリが足りなくなってるアプリがたくさんあるぞ

64bit Windowsを前提とした32bitアプリケーション延命法
〜 LAAオプションで32bitアプリケーションのメモリ不足問題を解消
https://www.webtech.co.jp/blog/optpix_labs/programing/6387/
2018/08/23(木) 20:12:19.28ID:k97Awv43
なぜ確率の問題?
2018/08/23(木) 20:16:43.95ID:sOVf8lyT
ちなみにこのブログ書いてるところはWindows用ソフトもいくつか出してるところだよ
2018/08/23(木) 20:18:49.99ID:sOVf8lyT
>>167

>>165のこと?

一応、32bitWindowsもサポートしてるがメモリが足りなくなってよく落ちるので
実際は64bit Windowsでしかまともに遊べないってこと
そういうゲームが既にある
2018/08/23(木) 20:23:47.22ID:k97Awv43
質問に全く答えてない件
2018/08/23(木) 20:34:21.09ID:sOVf8lyT
>>146
実際にどの程度、速度が変わるのか試してみて欲しいもんだな
ただの机上の空論じゃないのか?

大体、配列で何回もデータにアクセスするなら
32bitのDISPを毎回指定するオーバヘッドだってあるんだが
2018/08/23(木) 21:08:22.26ID:wxGNRrqx
32bitアプリも2G限定アプリも32bit OSも絶滅して良い
Windowsの話
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%くらいしか差はないよ
2018/08/23(木) 21:28:42.56ID:wxGNRrqx
250個並べてキャッシュに収まる?
2018/08/24(金) 00:12:57.34ID:568m+iHd
なんで訳分からなくなりそうになったのか理解できたw
4LRopBJnが変なんだな。

Microsoftが64bitでは絶対アドレスのインデックスは使わないって決めたんだから、その流儀に従うのが高級言語とリンクだよ。
2018/08/24(金) 00:23:58.73ID:568m+iHd
>>167
メモリが厳しいなら、ヒープが断片化すればメモリ確保できなくなっても不思議じゃないよ。
それなら確率的に落ちると思う。
2018/08/24(金) 01:48:40.54ID:PMMpdZPT
>>158
意味不明。

何の事言ってるの?
2018/08/24(金) 01:50:43.81ID:PMMpdZPT
>>159
いや、それはあなたの勘違い。

そのオプションを指定しても、EXEの中に入っている「初期化データ」のアドレス
が2GB以下に限定されるだけで、動的メモリは、理論上は、100GB でも一気に
確保できる。それは、再三言ってる。あなたは理解出来てないと思う。
2018/08/24(金) 01:54:49.18ID:PMMpdZPT
>>164
再三言ってるけど、あの/LARGEADDRESSAWARE:NO オプションを
付けても、「初期化データ」のアドレスが2GBに制限されるだけで、
new や malloc() などの、ヒープから確保される動的メモリは、64GBの
アドレス空間どこにあっても問題ないんだよ。
2018/08/24(金) 02:00:34.30ID:PMMpdZPT
>>173
そりゃ分かってるよ。

でも逆に、EXEファイルの中に最初から入っている「初期化データ」
の2GB制限とどっちが良いかの話になるんだよ。もちろん、動的メモリ
は何の制限も受けず、64GBアドレスが好きなように使える。

初期化データというのは、何かの埋め込みテーブルのための配列
だとか、文字列データとか、そういうものだよ。

巨大な3Dモデルデータ、テクスチャ、マップデータなどは、外部ファイル
にでも置いておけば、2GBの制限は受けず、仮想アドレスとしては
64BITまるまる使えるから。

実際、EXEの中にある初期化データが2GBを越えるという事は、
EXEファイルが2GBを越えるという事だから、そのアプリの起動
時には、有無を言わさず HDDなどから、2GBの読み込みが
始まってしまうことになる。
2018/08/24(金) 02:02:34.25ID:PMMpdZPT
>>179 >>180
【誤字訂正】
誤:64GBアドレス
正:64BITアドレス

言葉は間違っているが、中身は間違ってない。数学は100点、国語は赤点
の学生時代だったし。
2018/08/24(金) 02:18:09.88ID:PMMpdZPT
>>173
それでもやはり、1%の速度低下にはなったんだよね。

「初期化データの2GB制限」は、現実的には何の制限にもなってない
事は理解出来てる???? 動的メモリは、64BIT 自由に使える
んだよ。
2018/08/24(金) 04:19:33.40ID:CXKCSzYg
>>178、179
実際にやってみれば?
C言語でmallocでもvirtualallocでも
/largeaddressaware:noを付けると動的メモリも2GB以下しか確保できなくなるから
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
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);
}
2018/08/24(金) 04:45:01.40ID:CXKCSzYg
上のプログラムは64bitでも、32bitでもコンパイルは通るよ
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
2018/08/24(金) 07:19:19.64ID:ZkSPfVdV
>>173
これは最適化を知らないコード
250個並べちゃいけない
2018/08/24(金) 07:30:57.16ID:ZkSPfVdV
>>182
そこだけ抜き出して、
しかも最適化してないコードで1%
こんなコードは全体の中では非常にわずかだろうし
タイムクリティカル部分であれば最適化される

実質差が無いメリットの為に絶対アドレスに依存したコードにする
時代に逆行だ

それでも逆行したければ
0〜2Gのアドレスしか割り当てられない2G限定アプリにしろ
2018/08/24(金) 07:35:38.16ID:CXKCSzYg
>>188
250個並べても7KBくらい
1次命令キャッシュに丸ごと収まるぞ
2018/08/24(金) 07:38:24.94ID:ZkSPfVdV
uOPキャッシュ
2018/08/24(金) 07:53:32.13ID:CXKCSzYg
>>191
25個並べることにしてループ回数を一桁増やしたが早くならないぞ
そういうのを机上の空論というんだ
2018/08/24(金) 07:59:52.52ID:568m+iHd
なんか初心者スレの趣旨とずれまくりなんだけど。
コンパイラのABIが「変わった」のなら、それに合わせたのを紹介しないと。

Visual Cは64bitではインラインアセンブラも使えなくなったし、AVXやSSEは組み込み関数で大概は満足できるはずって判断されたのだろう。
今のご時世わざわざアセンブリ言語でプログラミングしたいって用途は動画のコーデックやフィルタプラグインDLL、将棋とかの思考ルーチンとかでしょ。
こういうのは2GB制限下でしか使えないコードでは困るはず。
2018/08/24(金) 08:09:12.98ID:568m+iHd
>>189
静的配列だとサイズが決まってるから、恐らく最適化されてポインタとオフセット(ディスプレースメント)に変換されるよね。
>実質差が無いメリットの為に絶対アドレスに依存したコードにする
>時代に逆行だ
これに同意。
2018/08/24(金) 12:53:22.92ID:7MrYBE0R
>>192
ヒント HTT
2018/08/24(金) 14:52:13.41ID:PMMpdZPT
>>185
自分は 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以下しか使えなくなる」
という文書が見つかりませんでした。

どこに書かれているか、ご指摘いただければ幸いです。
2018/08/24(金) 16:51:48.72ID:VlbdtNmU
実験したけど2GBまでだったよ
malloc

アドレスは32bitで保持出来る
32bitアプリからの移植用だろうね
2018/08/24(金) 16:55:58.09ID:VlbdtNmU
>>196
メモリはOS側の管理でしょ?
OSがアプリ種別を判別してアドレスを割り当てる

31bit
32bit
64bit

の3種類かな?
2018/08/24(金) 17:07:40.76ID:PMMpdZPT
>>199
リンカオプションによって、API の挙動まで変わってしまうんでしょうか。

そして、Win64 API の GlobalAlloc() などが返す値が 31 BIT までに
なるので、malloc() もそれにつられて、勝手に 31BIT までになると?

64BIT COFF だと、COFF Image に、/largeaddressaware:no かどうか
を示す BIT か何かが追加された???
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まで確保して終了する
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
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相対アドレッシングだよね?(エンコードは自信ないので)
2018/08/24(金) 19:58:50.48ID:568m+iHd
>>198
時々ポインタをDWORDに変換して構造体に突っ込んでたりすることがあるからね。
argeaddressawareは、こういうコードが含まれたアプリをどうしても64bitで動かさなきゃいけなくなった時とかに仕方なく使うオプションでしょう。
でないと、GlobalAlloc()が大きなアドレス返したら動かなくなるし。
2018/08/24(金) 20:08:42.11ID:568m+iHd
>>200
プロセスを起動する時にexeのLAAフラグを見てメモリとかハンドルを返すAPIが32bitに収まる値を返すように設定されるんだと思う。
こういうのはプロセスごとに32bitとかにも切り替えられる(この場合はシステムDLLは64bitとは別だけど)ので、
互換性を確保する仕組みが裏で動いてるはずだよ。
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
2018/08/24(金) 21:46:35.00ID:5OB8VNk6
>>203
VC++だと/FAオプションを指定するとアセンブラ出力もされるよ
ただ、64bitのVC++コンパイラが吐き出すアセンブラコードは
そのままではml64.exeでアセンブルできないけど
ml64.exeでアセンブルできるように修正できたらml64.exeでアセンブルする時に
/Flオプションを指定するとリスティングファイルを出力してくれる
2018/08/24(金) 22:08:39.28ID:568m+iHd
>>207
>>203は/FAscで出力された.codから抜粋したもので、リンク前だから変数のアドレスが変な値になってる。
最適化オプションつけ忘れてるのでimul使ってるけど、/O2でも配列へのアクセスはインデックスレジスタ付きなのは変わらなかった。

このサンプルでは配列の添え字がコンパイル時に推定できないようにしたのでインデックスレジスタ付きになってるけど、
普通のループでは、この部分は最適化されてポインタに変更されて、レジスタ間接とポインタ操作するコードになるはず。
2018/08/25(土) 04:35:15.70ID:gxBSyOuw
プロセスのアドレス空間が、4GB までだから

その内、Linux では1GB、Windows では2GB を、カーネル空間に割り当てているから、
残りのユーザー空間は、3GB, 2GB になる

カーネル空間は、全プロセス共通の空間だから、各プロセスで使えないアドレス
2018/08/25(土) 05:52:55.11ID:5KTEEpUR
64bit Windowsでの2GB制限ってのは、単にメモリ確保時のアドレスの割り当て方やハンドルの値が変わるだけで、
アクセスできない場所では普通に例外が発生するだけのこと。
/largeaddressaware:yesの状態では、32bitの範囲のアドレスがが割り当てられてないから
rip相対を使って静的変数のあるアドレスを取得するってことね。
2018/08/25(土) 05:57:44.86ID:5KTEEpUR
割り当てられてないってのは変だったね。
アクセス権限が与えられてないからってこと。
2018/08/25(土) 11:07:20.24ID:auNeFg4G
偉そうなもんだな。
もうちょっと、言い方ってもんを学んだ方がいい。
人間性に問題あるかも。
2018/09/03(月) 04:21:34.86ID:A+X9ST7o
アセンブラの命令を覚えたいのと
デバッガーを使いこなしたいんですが
何かお勧めの勉強方法はありますか?
C入門程度だけの知識だけでアセンブラは全く知りません

よろしくお願い致します
214デフォルトの名無しさん
垢版 |
2018/09/03(月) 11:24:23.57ID:dhYkuZhG
CPUは何?
2018/09/03(月) 12:38:16.62ID:f+M/nyW5
書いてないってことは決まって無いんだろう

Visual Studio Community 2017
x86 64bit
ml64.exe

が環境としては一番簡単かな
何もしない関数をアセンブラで作って
Cからその関数を呼ぶところから始めよう
2018/09/03(月) 20:27:11.25ID:A+X9ST7o
os10 64bitです
C++でアセンブラ使えるんですね
知りませんでした。そこら辺も調べてみます
デバッガーでコードを読んで書き換えられるようになりたいです
2018/09/03(月) 20:36:15.47ID:i7qE7EE1
マカーか
2018/09/04(火) 16:50:20.52ID:ErgP6cOz
横からだけど、
それに必要なのはバイナリからアセンブラコードを出力する逆アセンブラじゃないの?

それとも基礎知識として習得したいってことなのか
2018/09/04(火) 17:01:04.80ID:hMkkrsf+
チートしたい!
2018/09/04(火) 22:32:50.81ID:snmgssEj
>>218
これから勉強するって段階で逆アセはまだ早い。まずCで簡単なコード書いてアセンブラソース出力
それを見て少しずつ変更して動作を勉強。どきどき暴走させて遊ぶのがいい。
Cやアセンブラのソースがないバイナリを逆アセしても、逆アセはコードとデータの区別なしにコード化するから混乱する。
2018/09/04(火) 22:50:42.54ID:bj+tb6HS
回答ありがとうございます;
アセンブラの実行環境整える(実機だのエミュだの)用意するのが物凄い敷居高そうに感じるので
チートエンジンやollydbg?ってやつでオフライン用のゲームでも解析しながら
アセンブラ命令群を覚えようと思ってます。
アセンブラの命令を覚えるのだけなら後者でも力つきますかね?目標はウイルスのデバッグとか出来るようになりたいです
2018/09/05(水) 01:22:32.69ID:vQx16S6k
>>221
>目標はウイルスのデバッグとか出来るようになりたいです
どうしてそう反社会的な方ばっかり目がいくんだい。

これだから、ハッカー=クラッカー、悪者、のイメージが付く。
昔は、アセンブラといえば、速さのために学んだものなのに。

君みたいなのにはプログラムになんか興味を持たないで欲しい。
2018/09/05(水) 02:37:54.86ID:wyXCwUhn
>>どうしてそう反社会的な方ばっかり目がいくんだい。

そう…ではなくてですね
将来ウイルスとかランサムウェアの対策ツールとか作ってみたいから
デバッグスキル付けたいと思って、覚えたいと思いました。
http://www5c.biglobe.ne.jp/~ecb/assembler/assembler00.html 見て実行環境頑張って作って覚えようと思ったんですけど
とっつきづらすぎると思って;
てかVisualStudioって自分のコードアセンブラで出力したり出来るんですね
全然知りませんでした。ありがとうございます
2018/09/05(水) 03:52:48.57ID:EatH13os
ウィルスってね、勉強のつもりで作っても、いざ出来上がると使ってみたくなるもんなんだよね。
そういう誘惑に勝てるかどうか
2018/09/05(水) 06:27:13.70ID:wyXCwUhn
>>224
そういう方もいらっしゃるんですね。
プログラミング歴はもといパソコンも初心者レベルにしかない自分には縁のない響きですね・・

ところでC++のコードをvisualstudioでアセンブラ出力とはどうやるんでしょうか?
気になって調べてみたんですが デバック(D)→ウィンドウ→アセンブラ っと進むと出てくると書いてあるんですが
そんな項目ありません;
226デフォルトの名無しさん
垢版 |
2018/09/05(水) 11:13:33.31ID:/V9AsOwQ
debug.exe
debug64.exe
2018/09/05(水) 11:34:16.13ID:TWmx8fnR
OllyDbg とか、

うさぴょんの「うさみみハリケーン・スペシャルねこまんま」とか、
将棋AI「やねうら王」の作者、やねうらおの本「解析魔法少女 美咲ちゃん」とか

デバッガによるx86プログラム解析入門 【x64対応版】、うさぴょん、2014
2018/09/05(水) 11:55:15.09ID:gDSR0MtA
>>225
ソリューションエクスプローラーでソリューションの下にあるプロジェクトを選択してプロパティ
構成プロパティ→C/C++→出力ファイル→アセンブリの出力
■ このスレッドは過去ログ倉庫に格納されています