2012-03-23 1 views
1

をアセンブラにCのコードを翻訳:アセンブラ&C - 私はCで次のプログラムを書くの本を読んで、アセンブラコードに、この関数の呼び出しをconvet

int *p; /* pointer to integer */ 
int foo (int n, int *q) {} 
/* function get int and pointer to int, returns int */ 
/* Now, let's call the function: */  
*p = foo (*p, p); 

それに変換:

MOV EBX, [P] 
PUSH EBX 
PUSH DWORD [EBX] 
CALL foo 
MOV EBX, [P] 
MOV [EBX], EAX 
ADD ESP, 8 

それが正しいか、なぜ私はそれを理解できるように、私は、理解していなかったはずが、このようなコード:Pがあるので

MOV EBX, P ;; **CHANGE** 
PUSH EBX 
PUSH DWORD [EBX] 
CALL foo 
MOV EBX, P ;; **CHANGE** 
MOV [EBX], EAX 
ADD ESP, 8 

とそのポインタ。本書のようにMOV EBX, [P]を実行すると、整数である(アドレスではない)。PUSH DWORD [EBX]を実行すると、私たちは不規則な命令を得る。

どこが間違っていますか?

答えて

3

Pは、変数(ポインタ変数)のアドレスに相当するラベルです。 [P]はそのアドレスの値になります。これはポインタです。

ただし、一部のアセンブラでは、処理が少し異なります。 NASMとその派生物は大括弧などについてはかなり厳格です。 MASM、そうではありません。あなた自身が変数であるかのようにラベルを扱うことができるようになる時があります。 Pは、このような関数の内部であると仮定される

+0

Pがラベルであることをどのように理解していますか? 'int * p;と書いてあります。/*整数へのポインタ*/'あなたはあなたの答えを広げることができますか? Thanks –

+1

@Adam:アセンブリ言語は実際には "変数"を持たないので、 'P'はラベルです。レジスタとメモリがあります。いずれかが値を保持することができます。ただし、メモリを使用する場合は、値を格納する場所を知る必要があります。つまり、スタックポインタからのオフセット(ローカル変数の場合)、ラベル(スタティック/グローバルの場合)、または絶対アドレス(ふかふかしている場合)が必要です。 – cHao

+1

私が正しく覚えていれば、masmは 'mov ebx、p'を' mov ebx、[p] 'と解釈します。' p'のアドレスを望むなら 'mov ebx、offset p' –

1

:この場合

void foo(){ 
    int *p; /* pointer to integer */ 
    int foo (int n, int *q) {} 
    /* function get int and pointer to int, returns int */ 

    *p = foo (*p, p); 
} 

、Pアセンブリ用語で「可変の位置」または「標識」であろう。実際にはPはスタックに割り当てられますので、実際には次のようになります。

mov EBX,[p] ;; get the value of the p variable (a pointer) 
mov [EBX],10 ;; dereference the value of p and assign it to 10 
関連する問題