昨天看書遇到理解模糊的一段文字,在新浪微博聯絡到 @華章電腦科學 提出下面我對《CSAPP》第二版中一處譯文的理解,今天馬上就獲得了譯者在 豆瓣的回覆,在這裡。這說明了出版社和譯者都同樣重視本書。的確,這本書真的非常值得(儘管我才細細讀了百來頁),網購花了我 81 元。不過,今天剛好有個非常好的訊息,華章在新浪微博廣告該書的 最後一輪團購,看這裡,只需要 60 元(早該這樣子大優惠啦)。有價值的好訊息不妨廣而告之一下,相信讀完書之後我們都會有所得。其實51CTO讀書頻道也有這本書的 試讀,看這裡(我常在這裡獲得多本向圖書館推薦的書目)。下面是我在豆瓣該一段譯文的個人理解和解釋。
~ 第二版 P154 中倒數第二段,如下摘抄:
【這段程式碼從 caller 的棧幀中取出它的引數。因為幀指標已經移動,這些引數的位置也從相對於 %esp 的舊值 +4 和 0 的位置移到了相對於 %ebp 的新值 +12 和 +8 的位置。】
如果我的理解沒錯的話,上面的描述是說 “這些引數的位置” “移到了” 新的位置。但我根據上下文的理解是:“這些引數” 指的是 &arg1 和 &arg2 ,它們是採用了 “呼叫者儲存暫存器”儲存在呼叫者幀棧中,而子過程要呼叫時只是因為【幀指標 %ebp 和棧指標 %esp 都移動了】,所以相比【舊】的這兩個指標的值,如果現在要訪問這兩個引數,則會變成相對於【新】的指標的值加上【不同的偏移量】(只是不同的偏移量而已)。
所以我認為,譯文中說“這些引數的位置” “移到了” 新的位置似乎有點問題。另一個觀點是:呼叫子過程時幀指標 %ebp 和棧指標 %esp 都移動之後,子過程想要訪問的應該是【實參】(文中的程式碼是以指標傳遞引數的),而【實參】實際上還是待在【原來的記憶體地址】,根本沒有移動到哪裡去。
而文中翻譯為“引數的位置“ ”移到了…“ 是不是表明引數被拷貝後重新儲存在新的記憶體地址呢?我想應該不是吧?
在圖書館找來第一版的英文原版看了一下此段的描述,摘抄如下:
Body code in swap_add
1 movl 【8(%ebp)】, %edx Get xp
2 movl 【12(%ebp)】,%ecx Get yp
3 movl (%edx), %ebx Get x
4 movl (%ecx), %eax Get y
5 movl %eax, (%edx) Store y at *xp
6 movl %ebx, (%ecx) Store x at *yp
7 addl %ebx, %eax Set return value = x+y
This code retrieves its arguments from the stack frame for caller. Since the frame pointer has 【shifted】, the【locations】 of these arguments has 【shifted】 from 【positions】 12 and 16 relative to the old value of %ebp to 【positions】 +12 and+8 relative to new value of %ebp.
請注意我在原文中加上方括號的單詞,shift 可翻譯為 ”移動、改變“ 之意,個人認為,第一個 shifted 確實偏向於 ”移動“ 之意,因為 【幀指標的確移動了】;而第二個 shifted 則偏向於 ”改變、變化“,理由如前面所述,下面結合下一對單詞再解釋。
location 有 ”定位“ 之意,應該有一個參照點來比較而言,而 position 應該指 ”位置“,它應該是一個確切的、獨立的點。
綜合上面我對兩對單詞的理解,【”這些引數的位置“ 應該是指上面的程式碼段第1、2 行在訪問引數時所用的偏移量(聯絡上下文來理解)】,上面已經說了引數的位置(記憶體地址)沒有移動,所以【第二個 shifted 可能譯為”改變、變化“(相對於前面呼叫者幀段的訪問來說)更好】,而不是 ”移到了“。
我對此段的理解可譯為如下:
”因為幀指標已經移動,【對這些引數的定位】也從相對於 %esp 的舊值 +4 和 0 的位置【變成了】相對於 %ebp 的新值 +12 和 +8 的位置。“
不知道自己的理解有無差錯,如果有錯希望指正,謝謝!
【這段程式碼從 caller 的棧幀中取出它的引數。因為幀指標已經移動,這些引數的位置也從相對於 %esp 的舊值 +4 和 0 的位置移到了相對於 %ebp 的新值 +12 和 +8 的位置。】
如果我的理解沒錯的話,上面的描述是說 “這些引數的位置” “移到了” 新的位置。但我根據上下文的理解是:“這些引數” 指的是 &arg1 和 &arg2 ,它們是採用了 “呼叫者儲存暫存器”儲存在呼叫者幀棧中,而子過程要呼叫時只是因為【幀指標 %ebp 和棧指標 %esp 都移動了】,所以相比【舊】的這兩個指標的值,如果現在要訪問這兩個引數,則會變成相對於【新】的指標的值加上【不同的偏移量】(只是不同的偏移量而已)。
所以我認為,譯文中說“這些引數的位置” “移到了” 新的位置似乎有點問題。另一個觀點是:呼叫子過程時幀指標 %ebp 和棧指標 %esp 都移動之後,子過程想要訪問的應該是【實參】(文中的程式碼是以指標傳遞引數的),而【實參】實際上還是待在【原來的記憶體地址】,根本沒有移動到哪裡去。
而文中翻譯為“引數的位置“ ”移到了…“ 是不是表明引數被拷貝後重新儲存在新的記憶體地址呢?我想應該不是吧?
在圖書館找來第一版的英文原版看了一下此段的描述,摘抄如下:
Body code in swap_add
1 movl 【8(%ebp)】, %edx Get xp
2 movl 【12(%ebp)】,%ecx Get yp
3 movl (%edx), %ebx Get x
4 movl (%ecx), %eax Get y
5 movl %eax, (%edx) Store y at *xp
6 movl %ebx, (%ecx) Store x at *yp
7 addl %ebx, %eax Set return value = x+y
This code retrieves its arguments from the stack frame for caller. Since the frame pointer has 【shifted】, the【locations】 of these arguments has 【shifted】 from 【positions】 12 and 16 relative to the old value of %ebp to 【positions】 +12 and+8 relative to new value of %ebp.
請注意我在原文中加上方括號的單詞,shift 可翻譯為 ”移動、改變“ 之意,個人認為,第一個 shifted 確實偏向於 ”移動“ 之意,因為 【幀指標的確移動了】;而第二個 shifted 則偏向於 ”改變、變化“,理由如前面所述,下面結合下一對單詞再解釋。
location 有 ”定位“ 之意,應該有一個參照點來比較而言,而 position 應該指 ”位置“,它應該是一個確切的、獨立的點。
綜合上面我對兩對單詞的理解,【”這些引數的位置“ 應該是指上面的程式碼段第1、2 行在訪問引數時所用的偏移量(聯絡上下文來理解)】,上面已經說了引數的位置(記憶體地址)沒有移動,所以【第二個 shifted 可能譯為”改變、變化“(相對於前面呼叫者幀段的訪問來說)更好】,而不是 ”移到了“。
我對此段的理解可譯為如下:
”因為幀指標已經移動,【對這些引數的定位】也從相對於 %esp 的舊值 +4 和 0 的位置【變成了】相對於 %ebp 的新值 +12 和 +8 的位置。“
不知道自己的理解有無差錯,如果有錯希望指正,謝謝!
譯者龔老師的回覆:
2010-12-01 12:00:08 conjee
你的理解是對的。指標移動了,但是內容並沒有動,只是內容相對於指標的位置發生了變化。
我當時的翻譯確實沒有考慮得像你現在分析的這麼周到。
–龔奕利
我當時的翻譯確實沒有考慮得像你現在分析的這麼周到。
–龔奕利