2012-03-23 123 views
1

我读了一本书,在C写入下一个程序,convet这个功能来汇编代码调用:汇编&C - 翻译C'S代码汇编

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 

我不明白为什么它是正确的,我的理解它的代码应该是这样的:

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

而且因为P是一个指针。如果我们做MOV EBX, [P],正如本书所示,我们得到了整数(不是地址),然后如果我们做了PUSH DWORD [EBX],我们得到了不道德的指示。

我在哪里错了?

回答

3

P是一个标签,它等于变量的地址(你的指针变量)。 [P]将是该地址处的值,它是指针。

请注意,尽管如此,一些汇编程序有点不同。 NASM及其衍生工具对括号等非常严格。 MASM,不是那么多;有时候它会让你对待标签,就像它本身就是一个变量一样。

+0

你怎么理解,P是标签吗?这是写'int * p;/*指向整数* /'的指针。你能延长你的回答吗?谢谢 – 2012-03-23 15:41:06

+1

@Adam:'P'是一个标签,因为汇编语言没有真正的“变量”。有寄存器,还有内存;任何一个都可以持有价值。但是,如果您使用内存,则需要知道将值存储在何处。这意味着,您需要从堆栈指针(对于局部变量),标签(对于静态/全局变量)或绝对地址(如果感觉到青蛙)的偏移量。 – cHao 2012-03-23 16:09:22

+1

如果我没有记错的话,masm会将'mov ebx,p'翻译为'mov ebx,[p]' - 如果你想要'p'的地址,你必须写'mov ebx,offset p' – 2012-03-24 16:36:32

1

P被假定为这样的函数的内部:

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将通常堆栈INT他的情况进行分配,这意味着,当你做*p=10;你实际上是在做这样的事情:

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