设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

JavaScript是如何工作的:JavaScript的共享传递和按值传递(3)

发布时间:2019-04-18 17:47 所属栏目:21 来源:前端小智
导读:在调用 sum 函数之前,将其参数推入堆栈 ESP-[......] ESP-[100] [90] [.......] 然后,它将返回地址推送到堆栈。返回地址存储在EIP 寄存器中: ESP-[OldEIP] [100] [90] [.......] 接下来,它保存基指针 ESP-[OldEB

在调用 sum 函数之前,将其参数推入堆栈

  1. ESP->[......]  
  2. ESP->[ 100 ]  
  3. [ 90 ]  
  4. [.......]  

然后,它将返回地址推送到堆栈。返回地址存储在EIP 寄存器中:

  1. ESP->[Old EIP]  
  2. [ 100 ]  
  3. [ 90 ]  
  4. [.......]  

接下来,它保存基指针

  1. ESP->[Old EBP]  
  2. [Old EIP]  
  3. [ 100 ]  
  4. [ 90 ]  
  5. [.......]  

然后更改 EBP 并将调用保存寄存器推入堆栈。

  1. ESP->[Old ESI]  
  2. [Old EBX]  
  3. [Old EDI]  
  4. EBP->[Old EBP]  
  5. [Old EIP]  
  6. [ 100 ]  
  7. [ 90 ]  
  8. [.......]  

为局部变量分配空间:

  1. ESP->[ ]  
  2. [Old ESI]  
  3. [Old EBX]  
  4. [Old EDI]  
  5. EBP->[Old EBP]  
  6. [Old EIP]  
  7. [ 100 ]  
  8. [ 90 ]  
  9. [.......]  

这里执行加法:

  1. mov ebp+4, eax ; 100  
  2. add ebp+8, eax ; eaxeax = eax + (ebp+8)  
  3. mov eax, ebp+16  
  4. ESP->[ 190 ]  
  5. [Old ESI]  
  6. [Old EBX]  
  7. [Old EDI]  
  8. EBP->[Old EBP]  
  9. [Old EIP]  
  10. [ 100 ]  
  11. [ 90 ]  
  12. [.......]  

我们的返回值是190,把它赋给了 EAX。

  1. mov ebp+16, eax 

EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。

然后,恢复所有寄存器值。

  1. [ 190 ] DELETED  
  2. [Old ESI] DELETED  
  3. [Old EBX] DELETED  
  4. [Old EDI] DELETED  
  5. [Old EBP] DELETED  
  6. [Old EIP] DELETED  
  7. ESP->[ 100 ]  
  8. [ 90 ]  
  9. EBP->[.......]  

并将控制权返回给调用函数,推送到堆栈的参数被清除。

  1. [ 190 ] DELETED  
  2. [Old ESI] DELETED  
  3. [Old EBX] DELETED  
  4. [Old EDI] DELETED  
  5. [Old EBP] DELETED  
  6. [Old EIP] DELETED  
  7. [ 100 ] DELETED  
  8. [ 90 ] DELETED  
  9. [ESP, EBP]->[.......]  

调用函数现在从 EAX 寄存器检索返回值到 s 的内存位置。

  1. mov eax, 0x000002 ; // s 变量在内存中的位置 

我们已经看到了内存中发生了什么以及如何将参数传递汇编代码的函数。

调用函数之前,调用者将参数推入堆栈。因此,可以正确地说在 js 中传递参数是传入值的一份拷贝。如果被调用函数更改了参数的值,它不会影响原始值,因为它存储在其他地方,它只处理一个副本。

  1. function sum(num1) {  
  2. num1 = 30  
  3. }  
  4. let n = 90  
  5. sum(n)  
  6. // `n` 仍然为 90  

让我们看看传递引用数据类型时会发生什么。

  1. function sum(num1) {  
  2. num1 = { number:30 }  
  3. }  
  4. let n = { number:90 }  
  5. sum(n)  
  6. // `n` 仍然是 { number:90 }  

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读