public main
main proc near
Push ebp
mov ebp, esp
and esp, 0FFFFFFF0h
sub esp, 30h
mov dword ptr [esp], 8 ; size
call _malloc
mov [esp+2Ch], eax
mov dword ptr [esp+4], 4
mov eax, [esp+2Ch]
mov [esp], eax
call __start
上記のコードは、私が取り組んでいる大規模なプロジェクトの一部を表しています。このコードを同等のCに逆変換しようとしていますが、mallocがどのように機能するかを理解するのに苦労しています。
私は、8バイトが割り当てられるメモリのサイズになると考えています。ただし、この行についてはよくわかりません。
mov eax, [esp+2ch]
Mallocはeaxに何をしますか?
さらに、これは同等のCコードでしょうか?
int main(void)
{
int *ptr1;
ptr1 = (int *)malloc(sizeof(8));
*ptr1 = 4;
__start(*ptr1);
関数malloc()は、size
バイトの大きさのメモリブロックを割り当てます。要求されたメモリを割り当てることができる場合、ポインタがメモリブロックの先頭に返されます。
注:受信したメモリブロックの内容は初期化されません。
malloc()の構文:
void * malloc(size_t size);
パラメータ:
バイト単位のメモリブロックのサイズ。
戻り値:
要求が成功すると、メモリブロックへのポインタが返されます。関数が要求されたメモリブロックの割り当てに失敗した場合、NULLが返されます。また、サイズがゼロのmalloc()
が正常に呼び出されると、NULLが返される場合があります。
ローラー博士によるこのCS301講義 で述べられているように:
アセンブリ言語からMallocを呼び出す
これは非常に単純な関数です。rdiで、唯一のパラメーターとして必要な[〜#〜] bytes [〜#〜]の数を渡します。 「mallocに電話して」 raxで返される割り当てられたバイトへのポインタが返されます。後でスペースをクリーンアップするには、ポインターをrdiにコピーし、「call free」します(これを適切に行うにはスタックが必要なため、以下のfreeは省略します)。
これは、アセンブリメモリアクセスの完全な例です。私はmallocを呼び出して40バイトのスペースを取得します。 mallocは、このスペースの開始アドレスをrax(64ビットバージョンのeax)で返します。つまり、raxレジスタはポインタのように機能します。次に、通常のアセンブリブラケット構文を使用して、ポイントされたメモリから読み取りと書き込みを行うことができます。
mov edi, 40; malloc's first (and only) parameter: number of bytes to allocate extern malloc call malloc ; on return, rax points to our newly-allocated memory mov ecx,7; set up a constant mov [rax],ecx; write it into memory mov edx,[rax]; read it back from memory mov eax,edx; copy into return value register ret
Ecxレジスタを介してコピーするのではなく、次のように、角かっこ前の「DWORD」を使用して32ビットメモリの書き込みと読み取りを指定できます。
mov edi, 40; malloc's first (and only) parameter: number of bytes to allocate extern malloc call malloc ; on return, rax points to our newly-allocated memory mov DWORD [rax],7; write constant into memory mov eax,DWORD [rax]; read it back from memory ret
アセンブリ言語のmallocの場合..このリンクを参照 malloc