細々とした質問なので、複数質問することをお許しください。
アセンブリ言語で読めない箇所があります。
以前の質問で、以下のような例を示してもらいました(ありがとうございます。)
.section .rodata xx: .quad subr .text subr: inc %rax # ++rax ret .global aFunc aFunc: mov $0, %rax call subr call (subr) call *(xx) # 1 call *xx # 2 mov $subr, %rdx # 3 call *%rdx # lea subr(%rip), %rdx call *%rdx lea xx(%rip), %rdx call *(%rdx) ret
ですが、私の環境ではうまく行きませんでした。
1、2、3番と出来なかった所には番号が振ってあります。
(私にとってはこの3つができない方が納得いきます。)
1、*call subrとできない。
subrは絶対アドレスです。 なぜでしょうか?
1番,2番が仮にも出来る環境なら、call *subr これはできないとおかしいのではないでしょうか?
2,call subr 及び call (subr)
の結果が変わらないのは、ラベルに対して括弧を付けても意味が無いということですよね?
(付けても付けなくてもおk)
3,$subr は$は即値に付ける構文ですよね?
ラベルにも付けれるんですか?
(私の環境ではできませんでした。)
4,以上を見ていただければ、わかりますが・・・
アスタリスクは、絶対アドレスが入っているレジスタに対する構文ではないでしょうか?
ラベルに[*]を付ける方が納得がいかないんですが・・・・
(レジスタ以外に対するアスタリスクはすべてダメでした。)
5,もう1つ気になる事があります。
movq -8(%rbp), %rax movabsq $7812735413947559801, %rdx movq %rdx, (%rax) movabsq $7308533390257515808, %rcx movq %rcx, 8(%rax)
calloc関数を使って、ヒープを確保しその領域にstrcpy()で文字列を代入します。
しかしこれはオーバーフローではないでしょうか??
代入している即値が「8Byte」を完全に超えています。
64bitのレジスタに対してはオーバーフローです。
しかし、正常に動作しています・・・なぜでしょうか?
6, mov $1, %rax
最後に、qやl と言った文字をニーモニックにつけますが、
これは即値によって決めるものですか?それともレジスタの容量によって決めるものですか?
あ、言い方が悪かったです。ソースとデステネイションのどちらによって決めるものですか?
7,lea xx(%rip), %rdx | call *(%rdx)
これを1つにして、call *xx(%rip) と記述できます。(正常に実行できます。)
これも変です。
xx(%rip) の中身はアドレスです。
そのアドレスが指す領域内のアドレスが関数のポインタです。
なら、イメージ的には、call *(xx(&rip))こんな感じになります。
実際には文法エラーですが、call *xx(%rip)の記述はおかしいような気がするんですが・・・
これでは、%rip + xx のアドレスを絶対アドレスとしてcallしてしまっているように見えるのですが・・・・
わざわざ、オフセット付きの括弧となしの括弧の使い方を区別しているのに、これでは意味が無くなってしまいます。
[環境]
64bit Linux Debian系 intel CPU です。
回答2件
あなたの回答
tips
プレビュー