初心者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
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 位の値だった。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- こども家庭庁、2026年から“独身税”を開始、年収200万なら年4200円、年収400万なら年7800円 ★5 [お断り★]
- 伊東市長選、田久保氏の落選確実 元市議の杉本氏と元市長の小野氏が激しく競り合う [蚤の市★]
- サナエノミクスについて力説 積極的な財政出動で「所得増える 消費マインド上がる 税収増える」片山さつき財務大臣 ★2 [少考さん★]
- 【芸能】粗品、日本テレビに苦言 客のレベルが「かなり低い。あいつら分かってない」「拍手したいだけやねん」 [冬月記者★]
- B’z東京ドーム公演で後ろの客が大熱唱…「B’zの歌声に集中できない」注意すると笑いながら反論されモヤモヤ [muffin★]
- 女性天皇「賛成」69%、将来の皇位継承「不安」68%…読売世論調査 ★3 [蚤の市★]
- 地震 [794961135]
- 【実況】博衣こよりのえちえちボンバーマン大会🧪★6
- 地震
- 茶ぁしばこうやぁ···( ¨̮ )︎︎𖠚ᐝ5
- 最近イライラすることが多いんだがマジで対処法教えてくれ 全てのあらゆることに無性に腹立つんだよ… [434776867]
- 【朗報】イーロン・マスク「AIとロボットで誰も働かなくて良くなる。全員ニートで金銭も税金もないパラダイスみてぇな国を作りてえ」 [347751896]
