💜STEM玩具丹麥BAKOBA第二代漂流積木 💜
--好玩的跨學科教學模式--
【STEM玩具|幼幼腦力開發組/小童發明家同樂組/兒童創造者聯盟組/全家一起玩組】
這次依布爭取到很優惠的價格+贈品
跟依布的團最便宜也划算~贈品也很豐富!!!
團購時間:2021/01/04~2021/01/10
團購好康:
⭕️ BAKOBA第二代最優惠的售價,不買貴
⭕️ 附贈一本「專屬教案手冊」(通用版不限品項)
⭕️ 團購只要滿10人,每人會加贈一組零件包(零件當然越多越好玩啦~買起來!!)
⭕️ 團購(01/10前)會第一批優先出貨(最快3月底前實現)
優惠團購:https://forms.gle/J3pbthEV832195dp6 (01/10結團)
心得文:https://missibu.com/blog/post/bakoba
依布在挑選玩具時,除了好玩,我特別注重學習功能,能幫助到依芸學習的玩具我最喜歡,而這款STEM玩具丹麥BAKOBA第二代漂流積木就兼具了玩具/教具的功能唷
什麼是STEM教育?
根據字面上的意思,STEM四個英文字母分別代表:
✅S — Science(科學)
✅T — Technology(技術)
✅E — Engineering(工程)
✅M — Mathematics(數學)
也就是結合了cience科學、Technology技術、Engineering工程、Mathematics數學』的玩具唷~
讓小朋友在動手玩玩具當中,學習到這4個領域的精神
推薦理由
🔸安全
❶ 髒了可直接丟入洗衣機水洗,方便衛生
❷ EVA 材質,踩到不怕痛~
❸ 符合歐盟 EN71 玩具安全指令
🔸超耐玩
❶ 陸地+可以在水上漂浮!
❷ 特殊連接器,可與 LEGO 相容組合
❸ 可彎曲凹折,變化更多
🔸能力培養
❶ 獲得國際專業認證的 STEM 玩具
❷ 玩中強化創造、建構、邏輯、數理能力
❸ 同時培養語言表達、團隊協作情緒商數
🔸跨年齡層
❶ 無限變化擴充的零件設計,難易由你決定!
❷ 可以做出一輛卡車,也可以建出一座城市!
❸ 歐洲深沉色調、細緻質感,擺著也很美!
最近我都讓依芸完這組玩具,我拿的是幼幼腦力開發組49片組
依芸可以安靜的認真玩一段時間,而且因為材質柔軟,依芸在玩的時候完全無噪音,不會吵到妹妹維芸,這點真的超棒的~~
買給孩子當新年禮物我覺得很值得唷!!
#好評第二代 #新年禮物
#歐洲超過500間學校採用的優質STEM玩具
#最新第二代首度來台
#親子
#玩中學
「組合語言指令教學」的推薦目錄:
- 關於組合語言指令教學 在 依布小姐 Facebook 的最讚貼文
- 關於組合語言指令教學 在 李開復 Kai-Fu Lee Facebook 的最讚貼文
- 關於組合語言指令教學 在 Taipei Ethereum Meetup Facebook 的最佳解答
- 關於組合語言指令教學 在 看板ASM - [心得] 個人的x86 組合語言觀念筆記 的評價
- 關於組合語言指令教學 在 x86 Assembly Programming Tutorial 的評價
- 關於組合語言指令教學 在 微算機原理及應用(I)_林淵翔_單元三8051的組合語言程式設計 的評價
- 關於組合語言指令教學 在 [科大]微算機原理及應用_8051的組合語言程式設計 的評價
- 關於組合語言指令教學 在 林淵翔_單元三8051的組合語言程式設計_PART B - 指令集 的評價
- 關於組合語言指令教學 在 組合語言教學2023-在Facebook/IG/Youtube上的焦點新聞和 ... 的評價
- 關於組合語言指令教學 在 組合語言教學2023-在Facebook/IG/Youtube上的焦點新聞和 ... 的評價
- 關於組合語言指令教學 在 組合語言介紹 的評價
組合語言指令教學 在 李開復 Kai-Fu Lee Facebook 的最讚貼文
分享好文,中學生要學電腦嗎?
作者:創新工場CTO、人工智慧工程院執行院長 王詠剛
文章来自半轻人微信公众号(ban-qing-ren)
………………………………
朋友的孩子高中剛畢業,已拿到美國頂尖大學(非電腦專業)的錄取通知。疫情影響,不知何時才能去學校報到。孩子想抓緊學習一下程式設計,為大學打好基礎。這孩子找我聊了一個多小時,從如何學程式設計,聊到非電腦專業和電腦專業的路徑差異,又聊到如何從不同角度認識電腦與程式設計。聊得比較寬泛,不知是否對這孩子有用。
回想我自己的高中時代:那時雖迷戀程式設計,卻完全沒有懂行的人指導。在我們那個四線城市的廠礦中學裡,開設電腦興趣課的老師知道的資訊還沒我多。我高一時跑到北京中關村逛街,卻完全沒意識到中國第一代頂尖程式師當時就在我身邊的低矮辦公樓裡寫代碼(這話說得並不準確,比如求伯君那年就主要是在珠海做開發),鼎鼎大名的UCDOS、WPS、CCED就出自他們之手……我在當時街邊的一家書店(位置似乎就在今天的鼎好大廈對面)買到了許多種印刷品質極低劣的電腦圖書。用今天的標準看,那就是一批盜版影印或未授權翻譯的國外圖書。可那批書竟成了我高中時代最寶貴的程式設計知識來源。
顯然,我在高中時根本就是野路子學電腦。現在後悔也沒用,當時我的眼界或能觸及的資源就那麼多。如果能穿越回30年前,我該對喜歡程式設計的自己說些什麼呢?這些年,我與世界上最好的一批程式師合作過,也參與過世界上最有價值的軟體系統研發——我所積累的一些粗淺經驗裡,有哪些可以分享給一個愛程式設計的中學生?
【問題1】中學生要不要學電腦?
當然要!
每個中學生都要學。只不過——建議大部分中學生使用“休閒模式”,小部分(不超過10%)中學生使用“探險模式”。
啊?兩個模式?那我該進入哪個模式?⟹請跳轉至【問題2】
【問題2】選哪個模式?
你癡迷電腦嗎?比如,你玩遊戲時會特別想知道這遊戲背後的代碼是如何編寫的嗎?再比如,就算老師家長不同意你學電腦,甚至當著你的面把電腦砸了,你也要堅持學電腦嗎?如果是,恭喜你進入“探險模式”⟹請跳轉至【問題200】
你對數學有興趣嗎?比如,你看到街邊建築的曲線,就會在腦子裡琢磨曲線對應的函數或方程嗎?每當手裡攥著幾粒骰子,你就會不由自主地計算概率嗎?如果是,歡迎進入“探險模式”⟹請跳轉至【問題200】;當然,如果有些猶豫,也可以先進入“休閒模式”⟹請跳轉至【問題100】
即便你對電腦和數學興趣不大,家長、老師還是強烈建議你學電腦嗎?就算你一百個沒時間一千個不願意,家長、老師還是會逼著你學電腦嗎?如果是,建議你主動進入“休閒模式”並向家長、老師彙報說“我已經按照前谷歌資深軟體工程師的專業建議在認真學程式設計了”⟹請跳轉至【問題100】
其他情況,一律進入“休閒模式”。⟹請跳轉至【問題100】
【問題100】休閒模式 | 主要學什麼?
“休閒模式”將電腦視為我們生活、工作中的必備工具,主要學習如何聰明、高效、優雅地使用計算設備。這裡說的計算設備,包括所有形式的電腦、手機、遊戲機、智慧家電以及未來一定會進入生活的自動駕駛汽車。
什麼什麼?你已經會用電腦、會玩手機、會打遊戲了?別著急,慢慢往下看。
【問題101】休閒模式 | 我會用搜尋引擎嗎?
我知道你會用百度搜習題答案。但,習題答案不是知識。你會用搜尋引擎來搜索和梳理知識嗎?請試著用電腦和你喜歡的搜尋引擎來解決如下兩個問題:
(1)圓周率𝜋的計算方法有多少種?每種不同的計算方法分別是由什麼人在什麼時代提出的?借助電腦,今天人們可以將圓周率𝜋計算到小數點後多少位?將圓周率𝜋計算到小數點這麼多位元,一次大概需要花掉多少度電?
(2)全球大約有多少個廁所?在發展程度不同的國家,分別有多少比例的人可以享用安裝了抽水馬桶的衛生廁所?為什麼比爾·蓋茨曾大力推動一個設計新型馬桶的研發專案?比爾·蓋茨的公益組織在這個專案上大約花費了多少資金,最終收到了多大的效果?
如果你沒法快速得到上述問題的全部答案,那就給自己設一個小目標:一個月內,學會用搜尋引擎系統地獲取、梳理一組知識點的全部技巧。
【問題102】休閒模式 | 接下來學什麼?
建議學好典型的工具軟體。比如,我知道你會用Office了,但用Office和用Office是很不一樣的。對生活、學習、工作來說,學好、學透一個工具軟體比鑽研程式設計技巧更實用。
你會用Excel來管理班級公益基金的預算和實際收支情況嗎?
你會用Excel做出過去20年裡全球大學排名的演變趨勢圖嗎?
你會用Word排版一篇中學生論文嗎?論文中的圖表和最後的參考文獻部分該如何排版?
你會用Word編排一份班級刊物,包含封面、扉頁、目錄、插圖頁、附錄、封底等部分,可以在列印後直接裝訂成冊嗎?
PowerPoint呢?你有沒有研究過蘋果公司發佈會上那些幻燈片的設計?當約伯斯(多年以前)或蒂姆·庫克站在幻燈片前的時候,他們的演講思路是如何與幻燈片完美結合的?
還有哦,別忘了學學如何為數碼照片做後期,如何用電腦或手機剪視頻,如何為剪輯好的視頻配字幕,如何將照片、音樂、視頻等素材結合起來,做出一段吸引人的快手/抖音短視頻。
最後,抽空玩玩那些設計精妙的遊戲吧,比如《紀念碑穀》、《塞爾達傳說:曠野之息》之類;同時,遠離那些滿屏廣告,或者一心騙你在遊戲裡充值花錢的垃圾。
【問題103】休閒模式 | 不學學知識嗎?
當然要學知識。下面每種實用的電腦知識都夠大家學一陣子了。
(1)色彩知識:你知道同一張數碼照片在不同品牌的手機螢幕上、不同的電腦螢幕上、不同的智慧電視上顯示時,為什麼經常有較大色差嗎?你知道有一些色彩只適合螢幕顯示,不適合列印輸出嗎?你知道軟體工具裡常用的RGB、HSL之類的色彩空間都是什麼意思嗎?如何在設計PowerPoint幻燈片時選擇一組和諧美觀的色彩?
(2)字體知識:你知道什麼是襯線字體,什麼是無襯線字體嗎?你知道網頁中常用的英文字體都有哪些嗎?你知道商務演講時最適用于幻燈片的英文字體有哪些嗎?你知道電腦和手機常用的黑體、宋體、仿宋體、楷體等中文字體分別適合哪些實際應用場合嗎?你會將不同字體混排成一個美觀的頁面嗎?
(3)網路知識:你知道5G是什麼嗎?你知道5G和4G在通信頻寬、通信距離上的具體區別嗎?你知道什麼是路由器,什麼是防火牆嗎?你知道如何配置路由器,如何配置防火牆嗎?微信或QQ聊天時,對方發的文字、語音或視頻是如何傳送到你的手機上的?
(4)應用知識:淘寶中搜索得到的商品資訊是從哪裡來的?商品是按什麼方式排序的?為什麼購物APP經常會推薦給你一些曾經買過、看過的商品?你知道如何為自己建立個人網站嗎?你知道如何管理微信公眾號嗎?
(5)安全知識:你知道網路上的釣魚攻擊是怎麼回事兒嗎?你知道什麼是電腦漏洞嗎?你知道駭客為什麼想把一大批受攻擊的電腦變成可以遠端操控的傀儡機嗎?你知道為什麼現在很多手機APP都要通過短信發送驗證碼嗎?如果驗證碼被壞人截獲,你會面臨哪些風險?
這裡只是舉例。實用的電腦知識還有很多。大家可以自己發掘。
【問題104】休閒模式 | 我需要學程式設計嗎?
可以學,但不是必須。即便學,也只需要根據自己的需要,學那些最能幫你解決現實問題的部分。
【問題105】休閒模式 | 我該學什麼程式設計語言?
在“休閒模式”裡,電腦就是工具,程式設計也是工具,夠用就好。學什麼程式設計語言,完全看你想要電腦幫你做什麼。
• 如果你想對資料處理有更多自主權,那不妨學學Python;
• 如果你想做簡單的交互演示程式,那就先把JavaScript學起來;
• 如果你想更好、更快地寫論文,那不妨學學LaTeX(什麼什麼,LaTeX不是程式設計語言?你太小看LaTeX了);
• 如果你想學做簡單的手機APP,那麼,Android手機就學Java,蘋果手機就學Swift好了;
• 如果你只想知道程式設計是怎麼回事,那……從Python或JavaScript開始就行。其實,跟五六歲的小朋友一起學學Scratch圖形程式設計也不錯。
【問題106】休閒模式 | 我需要學人工智慧嗎?
在“休閒模式”裡,最需要學的不是“人工智慧的實現原理”,而是“什麼是人工智慧”,以及“人工智慧能做什麼,不能做什麼”。
• 在手機上試一試,人工智慧做語音辨識時能做到什麼水準?哪些話容易識別,哪些話不容易識別?
• 打開機器翻譯軟體,試一試哪些資訊翻譯得好,哪些資訊翻譯得不好?
• 手機上的拍照軟體一般都有人臉識別功能。試一試人臉識別在什麼場景下做得好,什麼場景下做得不好?
• 找一部講人工智慧的科幻電影,用自己的判斷解讀一下,電影裡哪些技術有可能成為現實,哪些技術存在邏輯矛盾。
【問題107】休閒模式 | 推薦什麼參考書、參考文獻?
書不重要,豆瓣評分7分以上的電腦應用、程式設計甚至科普類圖書都可以拿來翻翻。
直接在知乎裡搜索你想瞭解或學習的知識點可能更有效率。
如果你意猶未盡,覺得自己剛活動開筋骨,還想挑戰更高層次,歡迎進入“探險模式”。⟹請跳轉至【問題200】
否則,“休閒模式”到此結束。⟹請離開此問答
【問題200】探險模式 | 主要學什麼?
“探險模式”需要有挑戰精神。電腦科學的世界技術演進快,脈絡複雜,要想在探索時不迷路,你得通過有順序、有系統地學習電腦知識,慢慢構建出一張可以在未來幫你走得更遠的思維地圖來。
在“探險模式”裡,電腦就不止是一件能快速計算的工具了。電腦更像是我們大腦的一種延伸。這既包括認知能力的延伸,也包括認知邏輯的延伸。隨著學習深入,大家會逐漸體會到電腦所具有的多維度能力:
電腦是一種可以表示不同類型資訊(數、符號、文字、語音、圖像、視頻、虛擬空間、抽象邏輯)的“資訊管理機”;
同時,電腦也是一種可以連續執行指令以完成特定的資訊處理任務的“指令處理機”;
同時,電腦還是一種可以在知識與邏輯層面完成特定推理任務的“知識推理機”;
同時,電腦也是一種可以從人類給定的資料或自我生成的資料中總結規律,建立模型,自主完成某些決策的“智慧學習機”。
“探險模式”的目標就是盡可能準確地認識電腦,掌握有關電腦運行的最基本規律。有了這些基礎。未來在大學期間或工作中,你就能更容易地設計電腦軟硬體系統,或是設計出碳基大腦(人類)與矽基大腦(機器智慧)之間的最佳協作方案。
【問題201】探險模式 | 我的英語水準足夠嗎?
蘋果每年秋季的新品發佈會,不加字幕的話,你能聽懂多少?
能聽懂大部分:建議在學習電腦的過程中,盡可能使用英文教材、英文文檔。
能聽懂小部分:建議將原來準備學電腦的時間,分出一部分來學英語。
只能聽懂“你好”“再見”之類:⟹請離開此問答。然後,把原來準備學電腦的時間用於學英語,六個月後再回來。
【問題202】探險模式 | 我的數學水準足夠嗎?
如果你是數學和數學應用小能手——較複雜的數學問題總能快速找到核心思路,或快速簡化為簡單問題;很容易就能將抽象概念映射到具體的數學圖形,或將數學問題與相應的現實問題關聯在一起:請繼續探險之旅。
如果你應付正常數學課程感到吃力:建議將原來準備學電腦的時間,分出一部分來學數學。
如果你還搞不清楚什麼是方程、函數、集合、概率……:⟹請離開此問答。然後,把原來準備學電腦的時間用於學數學,六個月後再回來。
【問題203】探險模式 | 為什麼強調英語和數學?
(1)統計上說,最好的電腦參考資料大都是英文寫的,最好的電腦課程大都是用英文講的,最新的電腦論文大都是用英文發表的。
(2)函數、方程、坐標系、標量、向量、排列組合、概率這些中學數學裡會初步學習到的數學知識,是電腦科學的基礎。
【問題204】探險模式 | 電腦知識那麼多,正確的學習順序是什麼?
最重要的順序有兩個。建議先從順序一開始,學有餘力時兼顧兩個順序。
順序一:自底向上,即,自底層原理向上層應用拓展的順序。
電腦原理的基礎知識:
為什麼每台電腦(包括手機)都有CPU、記憶體和外部設備?
(馮·諾依曼體系結構的)記憶體中為什麼既可以存儲資料,也可以存儲指令?
CPU是如何完成一次加法運算的?
程式設計語言的基礎知識:
資料類型,值,變數,作用域……
語句,流程控制語句……
過程、方法或函數,類,模組,程式,服務……
編譯系統的基本概念:
電腦程式是如何被解釋或編譯成目標代碼的?
演算法和資料結構的基礎知識:
陣列,向量,鏈表,堆,棧,二叉樹,樹和圖……
遞迴演算法,排序演算法,二叉樹搜索演算法,圖搜索演算法……
應用層的基礎知識:
為什麼電腦需要作業系統?設備驅動程式是做什麼的?
網路通信的基本原理是什麼?流覽器是怎麼找到並顯示一個網頁的?
資料庫是做什麼用的?
虛擬機器是怎麼回事?
人工智慧系統的基礎知識:
先熟悉些線性代數、概率和數學優化的基礎知識。
什麼是機器學習?從簡單的線性回歸中體會機器學習的基本概念、基本思路。
什麼是神經網路?什麼是深度神經網路?為什麼神經網路可以完成機器學習任務?
如何使用PyTorch或TensorFlow實現簡單的深度學習功能?
順序二:自頂向下,即,自頂層抽象邏輯向下層具體邏輯拓展的順序。
• 電腦的本質是什麼?
• 什麼是圖靈機?什麼是通用圖靈機?
• 什麼是讀取﹣求值﹣輸出迴圈(Read–eval–print Loop,REPL)?
如何用自頂向下的方式理解(解析、解釋、編譯)一段程式碼?
• 靜態語言和動態語言的區別?
如何理解變數與資料類型之間的綁定關係?
• 什麼是函數式程式設計?
程式設計語言中,函數的本質是什麼?
函數為什麼可以像一個值一樣被表示、存儲、傳遞和處理?
• 什麼是物件導向?
類的本質是什麼?
如何用物件導向的方式定義個功能介面?
如何依據介面實現具體功能?
• 什麼是事件驅動?
什麼是事件?事件如何分發到接收者?
如何在事件驅動的環境中理解代碼的狀態和執行順序?
【問題205】探險模式 | 如何提高程式設計水準?
在掌握基本知識體系的基礎上,學好程式設計只有一條路:多程式設計,多參加程式設計比賽,多做程式設計題,多做實驗項目,多找實習機會——其中,能參與真實專案是最有價值的。
【問題206】探險模式 | 該從哪一門程式設計語言學起?
我個人推薦的程式設計入門語言(可根據情況任選):
Python
Java
Swift
C#
JavaScript / TypeScript
Ruby
……
可能不適合入門,但適合後續深入學習的語言:
C
C++
Go
Objective-C
組合語言
機器語言(CPU指令集)
Shell Script
Lua
Haskell
OCaml
R
Julia
Erlang
MATLAB
……
【問題207】探險模式 | 如何選參考書和參考資料?
(1)強烈推薦的參考書和參考資料:
• MIT、Stanford、CMU、UC Berkeley這四所大學中任何一個電腦專業方向使用的教學參考書或參考資料。網上可以查到這些學校電腦專業方向的課程體系,有的學校甚至公開了課程視頻。其中往往會列舉參考書和參考資料連結。
• 維琪百科(英文)上的數學、電腦科學相關條目。
• Github上star數在1000以上的開原始程式碼和開來源文件。
(2)強烈推薦但須小心辨別的參考資料:
知乎上的數學、電腦科學相關條目。使用時需要格外注意三件事:
儘量只看高贊答案或高贊文章;
辨別並避開廣告軟文;
辨別並避開純抖機靈的故事或段子。
Stack Overflow上的程式設計問題解答:
自己動手實驗,辨別解答是否有效。
CSDN上的程式設計問題解答:
自己動手實驗,辨別解答是否有效。
(3)其他推薦的參考書和參考資料:
國內專業作者寫作的專業技術書籍(豆瓣評分7分以上的)。
大廠(Google、Facebook、Microsoft、Amazon、阿裡、騰訊、百度、頭條等)資深工程師的技術公號、專欄、博客等。
著名圖書系列:如O’Reilly的動物封面的系列圖書(請注意最新版本和時效性)。
國內翻譯的著名技術圖書(譯本在豆瓣評分7分以上的)。
(4)儘量避免的參考書和參考資料:
• 已經過時的圖書或參考資料。
• 作者或譯者人數比章節數還多的專業圖書。
• 百度百科上的數學或電腦科學相關資料。
什麼什麼?你這篇問答居然沒有推薦一本具體的圖書?是,沒錯。如果你覺得即便有了上面的線索,自己還是找不到好書好資料,那也許你還是適合“休閒模式”⟹請跳轉至【問題100】
組合語言指令教學 在 Taipei Ethereum Meetup Facebook 的最佳解答
📜 [專欄新文章] 類 Python 的合約語言 Vyper 開發入門:與 Solidity 差異、用 Truffle 部署、ERC20 賣幣合約實做
✍️ 田少谷 Shao
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
有鑒於個人近期關注的 Uniswap 及 Curve 皆用 Vyper 實作,索性瀏覽了官方文件並嘗試一些開發工具,希望此文能減少一些讀者初嘗 Vyper 會遇到的麻煩!
Vyper and Solidity
Outline
一. Vyper 極簡介二. 與 Solidity 語法差異三. 開發、開發環境設置 1. 語法高亮 2. 本地 Vyper compiler 安裝 3. 使用 Truffle 操作 ERC20 - 安裝 Truffle - 發幣 - 寫個簡易賣幣合約四. 已知 Remix 問題 五. 結語
一. Vyper 極簡介
Vyper 是除 Solidity 外,以太坊上的另一智能合約 (Smart contract) 語言。其語法和 Python 相近,但畢竟也是寫合約的語言,邏輯差異不大,所以若熟悉 Solidity 應該不難理解用 Vyper 寫出的合約!
Vyper 主要被設計和 Solidity 的區別是安全性及可讀性,這部分會在下一段落及後方的實作中舉例說明。
二. 與 Solidity 語法差異
Vyper 與 Solidity 的差異有許多,在本段只就個人認為感受較深的三點進行說明,其他差異只進行翻譯,有興趣的讀者可以到官方文件詳細了解:https://vyper.readthedocs.io/en/latest/index.html
1. 沒有 modifier
Solidity 常見的 onlyOwner() modifier; 由於 gist 沒有 Solidity 的語法高亮,故截圖
在 Vyper 中單純用 assert 及 assert_modifiable 來進行條件檢查,兩者差別為若要檢查函數執行後的返還值,要用後者,如下圖:
Vyper 寫法
2. 沒有 Class inheritance 繼承
繼承是物件導向程式設計 (OOP) 的核心概念,但各種繼承關係有時候確實很複雜。Vyper 沒有繼承,這無疑大幅地增加了程式可讀性及安全性,以及降低審計程式碼的難度。在此提供一個例子供不熟悉 OOP 複雜之處的讀者有個概念:
source: https://consensys.github.io/smart-contract-best-practices/recommendations/#multiple-inheritance-caution
在上例中,contract A 的 fee 值 (因繼承自 contract B 和 C,故有 fee 一值) 是 5、a 值也是 5 (因繼承自 contract Final,故有 a 一值)。原因是 A 先繼承 B 再繼承 C,因此 contract A 中的 setFee() 是使用了 contract C 的 setFee(),而 a 值是由於 C(5),這代表 contract C 的 constructor (舊版本中即 function C(),函式名稱同 contract 名稱) 被傳入的值為 5。
稍微延伸一下以上概念,將 contract A 改成:contract A is C, B。如此一來,a 值還有 fee 值都會是 3,因為這次 A 先繼承 C 再繼承 B,因此最終吃到的值是 contract B 的。
以上就是 OOP 繼承的複雜之處的簡單範例說明,應該能稍微感受到爲什麼除去繼承後會大幅提高可讀性及安全性,畢竟即使是熟悉 OOP 的人有時頭腦一混亂也會開始懷疑自己寫的程式碼繼承結構是否正確 …
3. 沒有 dynamic array 動態陣列
這應該是目前 Vyper 設計中爭議最大的部分。沒有動態陣列代表在宣告陣列時需要宣告其長度,也就是說 Solidity 中的寫法 uint[], bool[] 等等,這些是不會出現在 Vyper 的。在 Vyper 中只能出現諸如:
# Vyper 的變數宣告方式為 變數名稱: 存取範圍(變數型態(若為陣列給長度))
values: uint256[10]participants: public(address[20])
可以看到上方的 uint256 及 address 兩陣列皆需要宣告長度,不能不宣告而使其動態地配置空間。
沒有動態陣列固然可以確保執行運算的範圍、次數,但一來動態陣列真的很方便、二來在 Solidity 有此功能而 Vyper 卻沒有的情況下可能會造成麻煩,詳見此一討論串:點我。
4. 沒有 inline assembly,程式碼中不會有組合語言
5. 沒有 function overloading,函式不會因傳入的參數數目不同而結果不同
6. 沒有 operator overloading,運算符號不會有不同於預設的自定義功能
7. 沒有無限迴圈,可免於 gas limit attack
8. 十進位定點數 decimal fixed point 而非二進位 (binary) 定點數,詳見:點我
三. 開發、開發環境設置
結論先講
開發 Vyper 的最佳姿勢目前個人認為是在本地裝上 Vyper compiler、用 Truffle 部署,並在撰寫時將檔名後加上 .py 就能有 Python 的語法高亮👌
1. 語法高亮 (syntax highlighting)
有語法高亮絕對是舒服地寫程式的第一步。
Remix 有 Vyper 的語法高亮,但一來個人目前不推薦使用 Remix 來撰寫 Vyper,原因詳見下方 4. 已知 Remix 問題;二來 Remix 的語法高亮其實也沒有很清楚,因此個人推薦:在本地開發,將檔名後加上 .py 就會有 Python 的語法高亮。
2. 本地 Vyper compiler 安裝
照官方說明使用 Python 的虛擬環境 virtualenv:
source: https://vyper.readthedocs.io/en/latest/installing-vyper.html#installing-vyper
簡單兩點提醒:
如果中間那行報錯但確實已經有 Python,則可能是版本問題。依照自己電腦上的版本改成相應的即可,ex: python3.6 改成 python3
進入虛擬環境後(檔案路徑前方應有 vyper-venv 的提示),使用此指令: vyper {檔案名稱}.vy,即可編譯 .vy 檔;使用完畢後輸入 deactivate 即可退出
3. 使用 Truffle 操作 ERC20
安裝 Truffle
Truffle 雖有冗餘的 migration 但也別無他法,畢竟 Remix 目前仍不完善 :(
下載流程可以照官方文件,使用 vyper-example:
source: https://github.com/truffle-box/vyper-example-box
由於我們會接上測試網 Ropsten,因此還要下載 truffle-hdwallet-provider:
source: https://github.com/trufflesuite/truffle-hdwallet-provider
接者就可以開始使用 Vyper 寫合約了!
發幣
由於 Vyper 的官方文件中已經有許多優質範例,因此本文希望來點不一樣但大家卻又很熟悉的…以 ERC20 為例(這千篇一律的主題xD):
用 Curve 的 ERC20 程式碼為範本,發一個幣(又要發…)
寫一個簡易賣幣合約
選擇這個主題一方面畢竟 ERC20 是以太坊的最大宗應用之一,二來有興趣的讀者可以透過讀 ERC20 的程式碼來熟悉 Vyper,並在看過本文的流程後對於用 Vyper+Truffle 來操作 ERC20 有完整的概念!
好的,首先複製一份 Curve 的 ERC20 程式碼(看到就順手拿來用),並複製到 Truffle 所在路徑的 contracts 資料夾中:https://github.com/curvefi/curve-contract/blob/pool_compound/vyper/ERC20.vy
由於第一點希望著重在跑一次流程,因此不改動合約的程式碼。
將 ERC20.vy 複製到 contracts 資料夾中後,到 migrations 資料夾開啟 2_deploy_contracts.js,首先將 require() 中的參數改為 ERC20.vy 的檔名 ERC20,再來依照自己喜好決定幣的名稱、代號、小數點位數及發行總量,輸入於 deployer.deploy() 中。
接著,為了和測試網 Ropsten 互動,需要將以下程式碼寫入 truffle-config.js。
第二行的 privateKeys 是帳號的私鑰。以下實作需要兩個帳號來操作,因此請從錢包匯入兩組私鑰(並非助憶詞)。
在第 13 行中 HDWalletProvider 此函式的第三個參數代表要用第幾個帳號最為預設帳號(部署合約等),第四個函數代表總共匯入幾組帳號。而第二個參數則是需要至 Infura 申請一個 project 來得到串接 Ropsten 的連結。這兩步驟並非本文重點,因此不詳細解說步驟,Google 搜尋關鍵字應該就會找到方法!
接著,就可以輸入以下指令來將代幣發佈到 Ropsten:
truffle deploy --network ropsten
有進入虛擬環境才可以編譯 .vy 檔,若忘記就會收到如下的錯誤訊息:
記得打開虛擬環境才能編譯 .vy 檔
成功後就可以在 contract address 中看到代幣發佈的位置,加入到 Metamask 中就可以看到。本文的例子是維尼代幣 Winnie the Coin, WTC ;)
contract address 便是 ERC20 的所在
Winnie the Coin, WTC
好了,到此測試網上又多了一個測試用的垃圾廢幣。
寫個簡易賣幣合約
賣幣合約中我想要簡單有兩個功能就好:付錢買幣 、結束銷售,以下就是程式碼。買幣的部分就不寫太詳細,固定價格為 0.01 Ether 可以買 500 代幣。
簡單說明幾點:
Solidity 的 constructor() 在 Vyper 中為 Python 風的 __init__():
函式的屬性(public, private, payable 等等)放在函式上方,與 Python 的修飾器位置相同
總之寫法跟 Python 很像,次方也一樣是用兩次乘法代表:**
變數前加上 self 代表是當前合約的變數/全域變數,因此非常容易與函式中的變數/區域變數做區隔
由於已經在第一行匯入了 ERC20 那份合約,因此透過將地址傳入合約當參數,就可以呼叫在該地址的合約:ERC20(self.tokenAddress) 。並且,可以將部署的合約存成一個變數 erc20 較方便
寫完合約後一樣要更改 migrations 資料夾中的 2_deploy_contracts.js 如下,將代幣所在的地址作為參數輸入。
由於先前已經部署過一次了,因此要重置才能再部署第二次,輸入以下指令:
truffle deploy --reset --network ropsten
部署成功之後就要來試著買幣啦!輸入以下來進入 console:
truffle console --network ropsten
成功進入後應該會看到 truffle(ropsten)> 的字樣。接著,首先取得部署的兩合約,並查看是否有返回合約資訊:
# ERC20 及 SellToken 是先前在 2_deploy_contracts.js 中的變數名稱,代表被部署的合約
let instance1 = await ERC20.deployed()instance1 # 印出 instance1 的資訊
let instance2 = await SellToken.deployed()instance2 # 印出 instance2 的資訊
再來,為了讓 SellToken 可以賣幣,要先用 ERC20 的合約匯幣到 SellToken 的合約。因此,輸入以下指令:
instance1.transfer(instance2.address, 10000)
# 這裡數字只要設為 > 500 就可以
接著,我們要利用第二個帳號去買幣(第一個帳號為預設帳號,因此就是代幣擁有者)。將帳號的資訊存入變數 accounts 中,再指定送出交易的帳號是第二個帳號。由於我個人匯入私鑰的順序是將第一個帳號存在 truffle-config.js 的 privateKeys[0]、第二個帳號存在 privateKeys[1],因此第二個帳號的地址就會在 accounts[1] 的位置:
let accounts = await web3.eth.getAccounts()
instance2.buyToken({from: accounts[1], value: 10000000000000000})
# value 為 10^16 是因為在 SellToken 的 buyToken 函式中買一次要 0.01 Ether, 即為 10^16 wei
然後應該就會在自己的第二個帳號中看到匯入的幣了~
最後,由於合約中結束銷售就是一個自殺 selfdestruct 函式,因此可以呼叫看看,第一個帳戶錢包中的錢應該會增加,因為第二個帳戶有付款買幣;並且,可以到 Ropsten 上瀏覽,應該能看到相關提示:
中間 contract 的右上角有 Self Destruct 的樣式
四. 已知 Remix 問題
Remix 目前有兩個版本,只有新版有 Vyper 的編譯器。在此整理目前遇到的問題,如果有人也遇到可以對照一下本處,可以省去很多自我懷疑xD
不會報錯
Remix 的編譯結果有時會是錯的、和本地端編譯出來的結果不同
舉上方的 SellToken 合約為例,將其複製到 Remix 中使用左邊的 Remote Compiler 有錯,但又不報錯 q_q (ERC20 的合約有在同檔案目錄)
左方有紅色三角形,代表編譯失敗,但沒有報錯訊息可以看…
getter function 竟然要花錢
用 Solidity 寫的合約,查詢 public 變數的值應該是不用消耗 gas 的,但不知何故查詢 Vyper 寫的合約的 public 變數卻要消耗 gas,如下圖…
可以看到中下方有 22026 gas 的消耗
Local compiler 無法使用
圖中的 Local Compiler 此選項,個人雖照官方文件執行 vyper-serve 但卻失敗,因此若有讀者成功希望能留個言不吝分享!
五. 結語
Vyper 作為一個比 Solidity 更新的合約語言,在寫程式碼的方面沒什麼問題,但相關的開發工具、學習資源等都遠不及 Solidity。
Vyper 主打的兩個特色:可讀性的部分相信看完上面的讀者應該已經有些感覺;安全性…小白如作者我倒是沒有感受到顯著的不同。況且 Solidity 已經發展許久,很多錯誤的寫法、知名的安全漏洞大家應該也很熟悉了,還有 Openzeppelin 提供安全合約寫法的範本,因此有待以後高人解說安全性是否真的是 Vyper 較好。
有興趣者可以查看 Vyper 的安全報告:點我,大意是目前 Vyper 的編譯器仍有許多問題待改進! (感謝 Chih-Cheng Liang 的提供)
本文對 Vyper 的介紹及其與 Solidity 的差異只講了個大概,欲知更詳細的介紹還是要麻煩讀者前往官方文件了:https://vyper.readthedocs.io/en/latest/index.html
最後,如果本文有任何錯誤,請不吝提出,我會盡快做修正;而如果我的文章有幫助到你,可以看看我的其他文章,歡迎一起交流 :)
田少谷 Shao - Medium
類 Python 的合約語言 Vyper 開發入門:與 Solidity 差異、用 Truffle 部署、ERC20 賣幣合約實做 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
組合語言指令教學 在 x86 Assembly Programming Tutorial 的推薦與評價
x86組合語言指令集○ 摘要:x86是組合語言的其中一種,在組合語言裡所有的運算都必須透過暫存器來計算,在這邊整理了組合語言的指令範例方便大家學習使用。 ... <看更多>
組合語言指令教學 在 微算機原理及應用(I)_林淵翔_單元三8051的組合語言程式設計 的推薦與評價
微算機原理及應用(I)_林淵翔_單元三8051的 組合語言 程式設計_PART H_旋轉 指令 、範例介紹 ... 分厘卡校準. 高屏區技術 教學 中心•7K views. ... <看更多>
組合語言指令教學 在 看板ASM - [心得] 個人的x86 組合語言觀念筆記 的推薦與評價
※ [本文轉錄自 C_and_CPP 看板 #1Cis6A7c ]
作者: purpose (purpose) 看板: C_and_CPP
標題: Re: [問題] C/C++ 中的 asm 該如何學起?
時間: Tue Oct 12 03:12:07 2010
發篇筆記
一、[簡介] 機器語言與80x86
二、[觀念] 組合語言—Intel Style 與 AT&T Style、MASM 與 NASM
三、[教學] 簡單連結範例—NASM 組合語言 與 C/C++ (Windows 平台)
-------------------------------------------------------------
一、[簡介] 機器語言與80x86
大家家裡用的計算機器叫做個人電腦 (PC)。
可以拿來安裝 Windows、Linux,甚至 Mac OS X...等作業系統。
個人電腦的 CPU 演變歷史,可以說就是 Intel 的歷史。從最早的16位元CPU:
「8088/8086 -> 80286」,再演化到32位元的 80386、80486...
後來因為商標不能用數字註冊,Intel 不使用 80586 命名,從586開始,
改名為歷史上的 Pentium CPU。
AMD 也差不多是在 Pentium 時代開始慢慢成為 Intel 在個人電腦處理器上的
競爭者。
可以想見 Intel 就是個人電腦處理器的「唯一制定者」,Intel自己做新的 CPU
也要向後相容以前的東西,就像 Windows 7 也得要能執行 Windows XP 的程式一般。
你在 286 寫的程式,拿去給 486 的 CPU 也要能跑。
所以「個人電腦 CPU = x86 家族」...好啦,可能有人不認同這句話。
你跟美國人講話就要講英文、跟法國人講法文;
跟 x86 家族的處理器講話,就要講「x86 機器語言」;
跟 Intel 8051 單晶片處理器溝通,就講「8051 機器語言」;
在算盤本裡面介紹的處理器是「MIPS」家族,就用「MIPS 機器語言」跟其溝通。
所有處理器裡面,x86家族功能當然是最強,每一代都有增加新功能,又要向後相容,
所以其實該語言最複雜、不規則、不好學。但只用些基本的功能的話,還是過得去的。
二、[觀念] 組合語言—Intel Style 與 AT&T Style、MASM 與 NASM
機器語言因為電路關係,原始形式就是 010101 這種二進位形式,但你喜歡也可以
轉成十六進位寫出來給別人看。
下面這是一個 x86 機器語言指令 (instruction):
05 0A 00 00 00 (十六進位表示)
用人類說法就是你告訴某顆 x86 家族的 CPU:
「把你的 eax 暫存器內容取出,將其跟10相加,再把結果寫回 eax 暫存器」
用C語言表示法就是:
「eax += 10;」
機器語言形式顯然太麻煩了。
於是發明了「助憶符號」,比如用 add 代表「相加這個運算動作」;
減法動作,用符號 sub 標記;
將資料從A處複製過去B處的動作,就用 mov 助憶符號標記。
add, sub, mov...等是運算子,而 eax 暫存器跟 10 是運算參與單元 (運算元)。
如果綜合以上講的運算子跟運算元,想要寫出完整指令時,還會有一個問題!
若有 eax, ecx 兩個運算元,想要把 eax 的值取出,複製到 ecx 去
到底該寫 mov eax, ecx 還是 mov ecx, eax ?
哪邊來源?哪邊目的?
AT&T、Intel 各自有一套語法慣例。
詳細資料參考這裡:
https://www.ibm.com/developerworks/library/l-gas-nasm.html
C語言 Intel AT&T
指派運算子的 靠最左邊的運算元 靠最右邊的運算元
左邊是目的地 是目的地。 是運算結果放置處。
int eax = 4; mov eax, 4 movl $4, %eax
(暫存器名稱前,需加 % 符號;
而且4這個立即數值前,需加 $ 符號;
且用 movl 表示 move long 這麼長)
西瓜靠大邊,跟大家一起用 Intel 慣例的寫法就好。
像上面 mov eax, 4 這樣子的指令形式,都叫「組合語言」,說穿了只是把當初
的「x86 機器語言」寫成比較容易看懂的形式而已。
既然這樣,那 x86 機器語言就一套,助憶符號跟暫存器也固定那幾個。
為什麼最後卻搞出 MASM、TASM、NASM、FASM...這麼多種組合語言呢?
MASM,軟體界霸主微軟推行的組合語言 (雖然微軟最近變心去搞 MSIL 的樣子?)
NASM,在台灣是僅次於微軟的選擇方案,而且跨多個作業系統平台。文件完整、
有中文書籍在講它,而且狀態穩定。
※ FASM,較新,類似於NASM,聽說比較快?
※ TASM,老牌子,現在很少人用了,但是有 Turbo Debugger 很強大,可以
對 16 位元執行檔做偵錯,偶爾也值得一用。
上面提到的組合語言都是 Intel Style,而 AT&T 會看到的地方,就是使用「gcc -S」
功能時會出現。但是可以用 objdump 去看 Intel Style 的組語。
如果是 gdb 偵錯則直接就有選項 disassembly-flavor intel 可以切換到
Intel 風格組語。
分別用 VC 跟 GCC ,一樣寫個 C 語言動態函式庫,把某個函數輸出,
我用 VC 時,可以在函數前面加上 __declspec(dllexport) 告知 VC 將該函數輸出。
也可以寫個「模組定義檔」(*.def) 去記載哪些函數要輸出。
但是這兩個方法都是 VC 特有,不是 C 語言規定的。
同樣狀況在組合語言亦同,MASM 也有一些組譯器指令是其專有,而 NASM 沒有。
甚至在語法上,兩者也有差異。
詳細資料:https://www.nasm.us/doc/nasmdoc2.html#section-2.2
NASM 對於「LABEL 符號」是有分大小寫的,MASM 沒有分。
(這不包含暫存器名稱,沒必要非寫 eax 而不寫 EAX,
也不包含 NASM 的假指令,比如 SECTION 大小寫都可以。)
而且 MASM 有些遭詬病的語法規範,NASM 有對其改進之。
對於 MASM
「某符號」要拿來「當成記憶體位址」用時,需加上 offset 修飾。
對於 NASM
覺得微軟這樣太麻煩,直接寫就一定是當位址用,不用加 offset。
MASM 的毛病是
如果寫組譯器指令如下,去定義兩個符號: (MASM、NASM 都支援這兩個假指令)
foo equ 1
bar dw 2
equ 指令很類似 #define pi 3.141421356 (...偷用別人的梗)
dw 這個假指令,是告訴組譯器把現在這個地方,所對應的記憶體位址,
取別名叫 bar,並且寫入 double-word (4位元組) 到此處,
存放值為 0x 00 00 00 02。
此時,如果 MASM 有兩個指令如下:
mov eax, foo ; foo 因為是 equ 設定出來的值,所以 eax 會得到 1
mov eax, bar ; bar 因為是「組合語言變數」,故 eax 得到值是 2
上面兩個指令,語法格式看起來完全一致,
但如果沒去觀看 foo 跟 eax 的假指令定義,就不能判定機器碼該翻成哪個。
如果是用 NASM,因為他強制規定只要是「間接取值」者,一律需加上中括號 []。
這個間接取值,意思是第一次取到的值,不是我要的,第二次取到的值才是我要的。
可以想成「間接取值 = 二次取值」。
換言之
mov eax, foo
mov eax, bar
對於 NASM 來說,不需要去看假指令定義,
因為 bar 跟 foo 都沒有用中括號,所以兩個都做一次取值就好。
亦即 mov eax, bar 會得到 bar 對應的記憶體位址,而不是 bar 的存放內容 2。
可是 MASM 很沒規律,因為 foo 是 equ 所定義,所以 eax 得到 1 (沒間接取值);
因為 bar 是一個 dw 定義的「組合語言變數」,所以將會做「間接取值」,先取得
bar 所對應的記憶體位址後,再到該位址再取一次值。
抓4位元組得到 2 來傳給 eax。
三、[教學] 簡單連結範例—NASM 組合語言 與 C/C++ (Windows 平台)
存成檔案 xx.c
---------------------------------------
#include <stdio.h>
int plusTen(int val);
int plusEleven(int x) {
return x+11;
}
int main() {
printf("return = %d\n", plusEleven(1));
printf("return = %d\n", plusTen(0x00123456));
return 0;
}
---------------------------------------
用 VC 編譯器的話,執行指令 cl /c xx.c 可以獲得對應的目的檔「xx.obj」
從 Visual Studio 200X 命令提示字元,去下這個 cl 指令,以省略環境變數的設定
存成檔案 fun.asm
---------------------------------------
section .text
global _plusTen
_plusTen:
push ebp ;函數初始化工作
mov ebp, esp ;函數初始化工作
mov eax, 0
mov ax, word [ebp+8]
add eax, 10
pop ebp ;函數結尾工作
ret ;返回呼叫函數 (caller),eax 是存放返回值用
---------------------------------------
去下載 NASM
https://www.nasm.us/pub/nasm/releasebuilds/2.09.02/win32/nasm-2.09.02-win32.zip
解壓縮後,執行指令 nasm -f win32 D:\Desktop\fun.asm
就能獲得一樣是 COFF 格式的目的檔 fun.obj。
簡單來說就是這個目的檔跟 cl /c 得到的目的檔有一樣格式。
最後再去「Visual Studio 200X 命令提示字元」下指令 link xx.obj fun.obj
就能得到 xx.exe 完成 C/C++ 跟 NASM 函數的連結了。
※對原理有興趣可以參考《程式設計師的自我修養》一書。
section .text
是 NASM 假指令,表示從這行指令以下的內容,翻譯成機器碼後
都要放到 .text 區去。每個 *.obj、*.exe 內部都有 .text 區段。
global
是 NASM 假指令,在這裡表示要把 _function 標籤包括的機器碼
視為全域函數。
在 C/C++ 你預設寫個函數,像上面的 plusEleven() 就自然會是
這裡說的這種「全域函數」。
使用 dumpbinGUI 工具,跳去 xx.obj、fun.obj 查看符號表,就可
看到 external 字眼。表示 xx.obj 可以調用 fun.obj 裡面寫
external 的符號,反之則反。
mov ax, word [ebp+8]
這個 ebp+8 是代表 plusTen() 函數的「參數1」
查一下 stack frame 的觀念,再用偵錯軟體觀察「函數呼叫」
進入前後的堆疊、暫存器變化,應該就能理解。
要說明的是,[ebp+8] 是「二次取值」,當第一次取值得到
ebp+8 位址假設是 0x0012FF74,接著要在這個地方做二次取值,在
C/C++ 要取幾個位元組的值是看該指標的資料型態。
如果是在 MASM,則是在中括號前寫 word ptr [ebp+8] 代表 2位元組;
若寫 byte ptr [ebp+8] 則代表 1位元組。
而 NASM 跟 MASM 差不多,但必須拿掉 ptr 字眼,否則會組譯錯誤。
因C語言還沒公開前,就已經留下一堆目的檔、一堆函數,他們都用正常的命名,
一些好記的名字都被用過了,所以 C 語言在使用函數時,其實一律自動加 _ 來命名。
因此原本的 C 函數呼叫雖然是 plusTen,但在 fun.asm 裡輸出的全域函數要寫成
_plusTen 才能讓 xx.c 可以連結到。
------------------------------------
關於「目的檔」,參考這篇:
https://en.wikipedia.org/wiki/Object_file
都只講微軟平台
在 DOS 時代目的檔名稱也都是 *.obj;執行檔名稱也都是 *.exe,
但這裡的 *.obj 其實是 OMF 格式 (Relocatable Object Module Format)。
跟你在 Windows 用 VC 編譯出來的目的檔 *.obj 不同。
用 nasm -f obj fun.asm 應該就是產生 OMF 格式的目的檔?
用 nasm -f win32 fun.asm 則是產生 COFF 格式的目的檔。
更精確來說這個 COFF 格式是微軟修改過的變種 COFF 格式。
你也可以叫它 PE/COFF 格式,甚至叫他 PE 格式也行,要解讀 PE 格式,其
第一選擇當然也是微軟提供 dumpbin,而軟體 dumpbinGUI 是圖形介面的前端。
真要說的話 dumpbin 也是一個前端,其實是呼叫 VC 的 link.exe,給隱藏選項
link /DUMP /ALL xx.obj。
https://en.wikipedia.org/wiki/Portable_Executable
PE 格式不一定是 *.exe 執行檔,也可以是 *.dll 也可以是 *.obj...等。
因為 VC 編譯出的目的檔都是 PE 格式,而 VC 的 link.exe 不能處理古早的
目的檔 OMF 格式,所以上面需要叫 nasm 用 -f win32 選項去產生 PE 目的檔。
也許會有某個很強的連結器,可以把 OMF 跟 PE 目的檔連結成 PE 執行檔吧?
甚至把 gcc 編出來的目的檔跟 PE 目的檔 link 成 PE 執行檔?
看有沒有人知道囉
------------------------------------
MASM 組譯器指令清單 https://msdn.microsoft.com/en-us/library/8t163bt0.aspx
剛好看到,補充上來。
------------------------------------
(怕以後忘記,再寫篇記錄,上文不變動,新增內容於下)
16位元記憶體模型—Segment:Offset (分段記憶體模型)
32位元記憶體模型—Flat Memory Model 加 Paging
( https://en.wikipedia.org/wiki/X86_architecture )
個人電腦 x86 家族的 CPU,在 16 位元時代是 8088/8086/80286 這三位;
而 x86 家族第一個 32 位元始祖是劃時代的 80386。
8088跟8086的位址匯流排都有20條線,每條線都是一端連接記憶體,一端連接
處理器,在高低電位變化下 (0、1),總共可有 2^20 種控制變化。
換言之,依照每個記憶體位址對應一個位元組的慣例,可以定位 2^20 大小的
記憶體位址;
80286 則進化到 24 條位址線,定址能力達 2^24,即 16M 記憶體。
省麻煩,把它當成跟 8088/8086 一樣,只能定址到 1M 記憶體就好。
※ 在 x86 的術語中,記憶體位址可以分成三種:
邏輯位址、線性位址、真實位址(物理位址)
必須先「邏輯位址→線性位址」,然後接著才是「線性位址→真實位址」。
自從32位元 CPU 出現 (自 80386 後),記憶體 Model 變成 Flat Memory,
邏輯位址就已經等於線性位址了。
然後是因為有「分頁機制」武力介入,所以需要先透過分頁機制轉換,線性位址
才會變成真正的物理位址。
而分頁機制是從 80386 開始使用 (保護模式的完整版也是從 80386 開始)。
那為什麼 16 位元處理器,不使用 Flat Memory Model?為什麼當初的邏輯位址
要先經過轉換才會變成線性位址?
因為16位元CPU內部,參與運算的暫存器當時都還停留在16位元
(如:ax, bx, cx, dx),甚至最重要的指令暫存器 (IP) 也是 16 位元,
故只有定位到 0~65535 也就是 64K 記憶體的能力。
Intel 用額外提供的四個「分段暫存器」(CS、DS、ES、SS),搭配其他暫存器後
,使得每次記憶體定址方式其實是 Segment:Offset,此時這種位址表達法叫
邏輯位址。
CS 是 Code Segment、DS 是 Data Segment、SS 是 Stack Segment ...
邏輯位址→線性位址,公式是:「Segment Register * 0x10 + Offset」
假設我們有個程式,裡面的「全域變數」(不是放在堆疊的那種區域變數),
有個很大的整數陣列,總共有 128K。當程式執行時,這些資料區段假設放在
「線性位址=物理位址」的 0x0 ~ 0x1FFFF 這段連續的記憶體空間裡。
在邏輯位址(以寫程式的角度去觀看的位址),這 128K 資料會被分成兩段,
第一段是 DS=0 且 offset = 0x0000~0xFFFF,第二段是 DS=1 且 offset
= 0x0000~0xFFFF。
換言之,如果我要把某陣列元素移到 ax 暫存器,指令可能長這樣
mov ax, word ptr[0x1234]
如果執行這行時 DS=0,則會取到物理記憶體位址 0x01234 處 (第一段);
如果執行這行時 DS=1,則會取道物理記憶體位址 1*0x10 + 0x1234 = 0x11234。
若要讀取最後一個位元組到ax,只要執行以下指令即可:
mov ds, 1
mov al, byte ptr[0xFFFF]
因為不知道當時的 DS 值為多少,所以保險點,先設定 DS,然後因為 ax 是
16 位元,不必用到這麼大。所以用 al 存放即可。 al 就是 ax 暫存器
低 8 位元別名。
(ax 在 32 位元以上的 CPU 時,其實也是 eax 暫存器的低16位元處別名)
現今的執行檔,比如 PE 執行檔,往往內部都有分 .text (.code)、.data,
可能就是承襲當初的記憶體分段機制?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 124.8.140.240
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 124.8.128.171
... <看更多>