user-0 提问: 使用结构体指针做为参数的疑问

回复:
user: user-1
content: 引用 11 楼 u013992933 的回复:mov 不是 dst src这种格式吗？怎么汇编里看上去是反过来的？ ×86汇编有两种语法，intel语法和AT&T语法，两种语法的源操作数和目的操作数位置相反

user: user-2
content: 参数如果是指针直接一个Lea就可以了， 如果是值，他选要把他全部压入栈中

user: user-0

user: user-2
content: 引用 6 楼 u013992933 的回复:00000000004004c2 <foo>:   4004c2:	55                   	push   %rbp   4004c3:	48 89 e5             	mov    %rsp,%rbp   4004c6:	89 7d fc             	mov    %edi,-0x4(%rbp)   4004c9:	48 89 f1             	mov    %rsi,%rcx   4004cc:	48 89 d0             	mov    %rdx,%rax   4004cf:	48 89 4d e8          	mov    %rcx,-0x18(%rbp)   4004d3:	48 89 45 f0          	mov    %rax,-0x10(%rbp)   4004d7:	c7 45 fc 03 00 00 00 	movl   $0x3,-0x4(%rbp)   4004de:	c6 45 e8 64          	movb   $0x64,-0x18(%rbp)   4004e2:	c9                   	leaveq    4004e3:	c3                   	retq     00000000004004e4 <main>:   4004e4:	55                   	push   %rbp   4004e5:	48 89 e5             	mov    %rsp,%rbp   4004e8:	48 83 ec 20          	sub    $0x20,%rsp   4004ec:	c7 45 fc 64 00 00 00 	movl   $0x64,-0x4(%rbp)   4004f3:	c6 45 e0 01          	movb   $0x1,-0x20(%rbp)   4004f7:	66 c7 45 e2 14 00    	movw   $0x14,-0x1e(%rbp)   4004fd:	c7 45 e4 2c 01 00 00 	movl   $0x12c,-0x1c(%rbp)   400504:	48 c7 45 e8 a0 0f 00 	movq   $0xfa0,-0x18(%rbp)   40050b:	00    40050c:	48 8b 4d e0          	mov    -0x20(%rbp),%rcx   400510:	48 8b 55 e8          	mov    -0x18(%rbp),%rdx   400514:	8b 45 fc             	mov    -0x4(%rbp),%eax   400517:	48 89 ce             	mov    %rcx,%rsi   40051a:	89 c7                	mov    %eax,%edi   40051c:	e8 a1 ff ff ff       	callq  4004c2 <foo>   400521:	c9                   	leaveq    400522:	c3                   	retq      400523:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)   40052a:	00 00 00    40052d:	0f 1f 00             	nopl   (%rax) --------------------------------------------------------------------------------------- typedef struct st{ 	char a; 	short b; 	int c; 	long d;   }st;  void foo(int i,st st){ 	i=3; 	st.a=100; 	return; }  void main(){ 	int i=100; 	st st={1,20,300,4000}; 	foo(i,st);  return; } 你再传一个指针试一下，比较两者的区别

user: user-0
content: 00000000004004c2 <foo>:   4004c2:	55                   	push   %rbp   4004c3:	48 89 e5             	mov    %rsp,%rbp   4004c6:	89 7d fc             	mov    %edi,-0x4(%rbp)   4004c9:	48 89 f1             	mov    %rsi,%rcx   4004cc:	48 89 d0             	mov    %rdx,%rax   4004cf:	48 89 4d e8          	mov    %rcx,-0x18(%rbp)   4004d3:	48 89 45 f0          	mov    %rax,-0x10(%rbp)   4004d7:	c7 45 fc 03 00 00 00 	movl   $0x3,-0x4(%rbp)   4004de:	c6 45 e8 64          	movb   $0x64,-0x18(%rbp)   4004e2:	c9                   	leaveq    4004e3:	c3                   	retq     00000000004004e4 <main>:   4004e4:	55                   	push   %rbp   4004e5:	48 89 e5             	mov    %rsp,%rbp   4004e8:	48 83 ec 20          	sub    $0x20,%rsp   4004ec:	c7 45 fc 64 00 00 00 	movl   $0x64,-0x4(%rbp)   4004f3:	c6 45 e0 01          	movb   $0x1,-0x20(%rbp)   4004f7:	66 c7 45 e2 14 00    	movw   $0x14,-0x1e(%rbp)   4004fd:	c7 45 e4 2c 01 00 00 	movl   $0x12c,-0x1c(%rbp)   400504:	48 c7 45 e8 a0 0f 00 	movq   $0xfa0,-0x18(%rbp)   40050b:	00    40050c:	48 8b 4d e0          	mov    -0x20(%rbp),%rcx   400510:	48 8b 55 e8          	mov    -0x18(%rbp),%rdx   400514:	8b 45 fc             	mov    -0x4(%rbp),%eax   400517:	48 89 ce             	mov    %rcx,%rsi   40051a:	89 c7                	mov    %eax,%edi   40051c:	e8 a1 ff ff ff       	callq  4004c2 <foo>   400521:	c9                   	leaveq    400522:	c3                   	retq      400523:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)   40052a:	00 00 00    40052d:	0f 1f 00             	nopl   (%rax) --------------------------------------------------------------------------------------- typedef struct st{ 	char a; 	short b; 	int c; 	long d;   }st;  void foo(int i,st st){ 	i=3; 	st.a=100; 	return; }  void main(){ 	int i=100; 	st st={1,20,300,4000}; 	foo(i,st);  return; }

user: user-3
content: 无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！  调用约定 https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx

user: user-2
content: 引用 2 楼 u013992933 的回复:可是我在看汇编时，并没有找到cpoy相关的代码...... 大佬，可不可举个栗子 你没看懂汇编，把你看到的汇编贴出来

user: user-4
content: 如果形参是结构，那么会占用一部分内存空间（指针只占4个字节--32位系统）。  引用 2 楼 u013992933 的回复:可是我在看汇编时，并没有找到cpoy相关的代码...... 大佬，可不可举个栗子 值传递，是需要将实参拷贝至形参的。形参是自定义函数上的变量。而指针，即将实参的地址传过去。用指针跳转要比拷贝实参至形参效率高多了。这也是指针的优势。 对于这样的问题，我们要考虑结构体较大时，优势越明显。

user: user-0
content: 可是我在看汇编时，并没有找到cpoy相关的代码...... 大佬，可不可举个栗子

user: user-1
content: 如果直接使用结构体作为参数，实际过程是创建一个临时对象传给函数的，也就是要拷贝一次，效率自然就低了。用指针不用创建对象的过程，效率就高。这是函数传参的特点。

user: user-5
content: 我觉得在这个问题上，你还用不着去看汇编。 你弄懂函数参数是“值传递”，和自定义对象在值传递时需要做什么，就应该明白了。 1. 什么是值传递？ void foo(int v){ //这里的v和外面的a其实是两个变量，函数调用时，做了如下操作：v = a;   v = 2; //这里的v不是main中的a，所以修改v后，a不会改变！ } int main() {   int a = 1;   foo(a);   assert(a == 1); //a没有改变   return 0; } 2. 值传递时做了什么？ 基本数据类型，看不出来，或者说什么也没做，只是赋值；而自定义对象则不同：在栈上分配对象需要的内存空间，然后调用(复制)构造函数！这也耗时的主要原因。 struct A{ A(){} A(const A&){cout << "复制构造函数被调用" << endl;} }; void foo(A){} int main() {   A a;   foo(a);   return 0; }

user: user-3
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

user: user-0
content: 还有一个疑问是。 mov 不是 dst src这种格式吗？怎么汇编里看上去是反过来的？  多谢大佬

user: user-0
content: 大佬，. 1.0x1c 0x1e地址的值怎么没有放寄存器里，结构体不是四个成员变量吗？ 2.为什么偏移都是4，成员的类型都不一样啊？ 3.0x4偏移那个0x64是什么用啊？