我已經看了彙編輸出下面的一段代碼,我驚呆了:Lambdas作爲封閉環境。 RIP的重要作用註冊
int x=0, y=0; // global
// r1, r2 are ints, local.
std::thread t([&x, &y, &r1, &r2](){
x = 1;
r1 = y;
});
!std::thread t([&x, &y, &r1, &r2](){
<lambda()>::operator()(void) const+0: push %rbp
<lambda()>::operator()(void) const+1: mov %rsp,%rbp
<lambda()>::operator()(void) const+4: mov %rdi,-0x8(%rbp)
<lambda()>::operator()(void) const+18: mov -0x8(%rbp),%rax
<lambda()>::operator()(void) const+22: mov (%rax),%rax
! x = 1;
<lambda()>::operator()(void) const()
<lambda()>::operator()(void) const+8: movl $0x1,0x205362(%rip) # 0x6062ac <x>
! r1 = y;
<lambda()>::operator()(void) const+25: mov 0x205359(%rip),%edx # 0x6062b0 <y>
<lambda()>::operator()(void) const+31: mov %edx,(%rax)
!
!});
<lambda()>::operator()(void) const+33: nop
<lambda()>::operator()(void) const+34: pop %rbp
<lambda()>::operator()(void) const+35: retq
爲什麼地址x
,y
確定涉及到RIP
。 RIP
是一個指令指針,所以它似乎是瘋狂的。特別是,我從來沒有見過這樣的事情。 (也許我還沒有看到很多東西:))。
對我來說唯一的解釋是,lambda是一個閉包,並且從特定位置獲取環境變量與RIP
有一些共同之處。
在x86_64中引入了RIP相對尋址。內存引用是相對於指令指針的。它在創建與位置無關的代碼中很有用。你可以在這裏找到一個描述:https://www.tortall.net/projects/yasm/manual/html/nasm-effaddr.html –
http://stackoverflow.com/q/18447627/995714,http:// stackoverflow .com/q/3250277/995714 –
PIC在64位環境中很好,因爲立即數仍然可以是32位。 –