Assembly 汇编器及;C-翻译C';汇编代码

Assembly 汇编器及;C-翻译C';汇编代码,assembly,x86,Assembly,X86,我读了一本用C编写下一个程序的书,并将此函数的调用转换为汇编代码: 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

我读了一本用C编写下一个程序的书,并将此函数的调用转换为汇编代码:

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
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);
}
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
因为p是一个指针。如果我们像书中建议的那样,使用MOV EBX,[P],我们得到的是整数(不是地址),然后如果我们使用DWORD[EBX],我们得到的是非法指令


我错在哪里?

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


不过请注意,有些汇编程序的工作方式有点不同。NASM及其衍生产品对括号等都非常严格。马斯姆,没那么多;有时,它会让您将标签视为一个变量。

p
是一个标签,等同于变量(指针变量)的地址
[P]
将是该地址的值,即指针


不过请注意,有些汇编程序的工作方式有点不同。NASM及其衍生产品对括号等都非常严格。马斯姆,没那么多;有时,它会让您将标签视为一个变量。

p被假定为位于如下函数中:

MOV EBX, P   ;; **CHANGE**
PUSH EBX
PUSH DWORD [EBX]
CALL foo
MOV EBX, P ;; **CHANGE**
MOV [EBX], EAX
ADD ESP, 8
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);
}
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
在这种情况下,p将是“变量的位置”或汇编术语中的“标签”。因为在这种情况下P通常会在堆栈上分配,这意味着当您执行
*P=10您实际上正在执行以下操作:

MOV EBX, P   ;; **CHANGE**
PUSH EBX
PUSH DWORD [EBX]
CALL foo
MOV EBX, P ;; **CHANGE**
MOV [EBX], EAX
ADD ESP, 8
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);
}
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

假设p位于如下函数的内部:

MOV EBX, P   ;; **CHANGE**
PUSH EBX
PUSH DWORD [EBX]
CALL foo
MOV EBX, P ;; **CHANGE**
MOV [EBX], EAX
ADD ESP, 8
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);
}
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
在这种情况下,p将是“变量的位置”或汇编术语中的“标签”。因为在这种情况下P通常会在堆栈上分配,这意味着当您执行
*P=10您实际上正在执行以下操作:

MOV EBX, P   ;; **CHANGE**
PUSH EBX
PUSH DWORD [EBX]
CALL foo
MOV EBX, P ;; **CHANGE**
MOV [EBX], EAX
ADD ESP, 8
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);
}
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

你如何理解P是一个标签?写
int*p;/*指向整数的指针*/
。你能扩展你的答案吗?Thanks@Adam:
P
是一个标签,因为汇编语言实际上没有“变量”。有寄存器,有内存;任何一个都可以持有一个值。但是,如果使用内存,则需要知道将值存储在何处。这意味着,您需要堆栈指针的偏移量(对于局部变量)、标签(对于静态/全局变量)或绝对地址(如果您感觉不舒服)。如果我没记错,masm会将
mov ebx,p
转换为
mov ebx,[p]
-如果您想要
p
的地址,您必须编写
mov ebx,偏移量p
您如何理解p是一个标签?写
int*p;/*指向整数的指针*/
。你能扩展你的答案吗?Thanks@Adam:
P
是一个标签,因为汇编语言实际上没有“变量”。有寄存器,有内存;任何一个都可以持有一个值。但是,如果使用内存,则需要知道将值存储在何处。这意味着,您需要堆栈指针的偏移量(对于局部变量)、标签(对于静态/全局变量)或绝对地址(如果您感觉不舒服)。如果我没记错,masm会将
mov ebx,p
转换为
mov ebx,[p]
-如果您想要
p
的地址,您必须编写
mov ebx,偏移量p