2015年6月23日 星期二

[PCB][Web]中國IPC

最近因接觸8層板PCB,對於PCB製程及上件不熟悉,故這邊主要放上相關網站做參考,方便未來由此切入,此處不定期更新~~~

IPC (Association Connecting Electronics Industries)
http://www.ipc.org/default.aspx

中國網站為
http://www.ipc.org.cn

主要是說明連結這篇文章
從產品失效看PCB設計之關連性 

至於國內我想很多人都follow
工作熊的網誌吧!!!
http://www.researchmfg.com/



2015年6月18日 星期四

[gcc][debug]淺談在codeblocks下的Debug

1.目前使用的版本號是CodeBlock13.12(以下簡稱CB)安裝的是一開始沒有帶minGW的版本
 codeblocks-13.12-setup.exe,這個是沒有帶compiler的版本,相關的說明請到這Link
 觀看。
2.編譯器使用的版本是tdm64-gcc-4.9.2-3.exe,這個版本是64bit的,如果你想使用32bit
 的版本,請下載tdm-gcc-4.9.2.exe

3.我的作業系統是Win7 64bit

開始說明怎麼使用Debug看些東西
C語言的程式碼如下:

CV_INLINE  CvSize  cvSize( int width, int height )
{
    CvSize s;

    s.width = width;
    s.height = height;

    return s;
}


該段程式碼在Debug模式下的組合語言如下:
0x00436760 push   %ebp
0x00436761 mov    %esp,%ebp
0x00436763 sub    $0x10,%esp
0x00436766 mov    0x8(%ebp),%eax
0x00436769 mov    %eax,-0x8(%ebp)
0x0043676C mov    0xc(%ebp),%eax
0x0043676F mov    %eax,-0x4(%ebp)
0x00436772 mov    -0x8(%ebp),%eax
0x00436775 mov    -0x4(%ebp),%edx
0x00436778 leave
0x00436779 ret
基本上請先開啟下圖看到的三個視窗
Memory dump
CPU Registers
Disassembly


執行的時候請點Step into instruction




開啟後畫面大概如下:
<執行前>







<執行後>









C語言的說明:
程式只是要把width和heigth這兩個值透由宣告為CvSize型態的s回傳回去

在這個例子中:
width = 129(0x81),這個值一開始放在0x28fdd0位址裡面
heigth = 21(0x15),這個值一開始放在0x28fdd4位址裡面

在組合語言裡面就開始不一樣了!!!!
開始講解組合語言內容前,先大概講一下這三個暫存器還有sub $0x10,%esp的由來
eip(Extended Instruction Pointer)=>這個暫存器存的值是表示程式執行到哪,
參考Disassembly執行前後的圖,看到類似下面這張圖的箭頭就是eip的值



執行前 eip = 0x00436760
執行後 eip = 0x00436779
總共花了25(0x19)個執行時間
這個就要講到operation code
這以後有機會在說明.....

ebp(Extended Base Pointer)=>基底指標,當組合語言要執行return時,會以這裡面的值當作他要回去的位址。值錯了就回不去了!!!

esp(Extended Stack Pointer)=>堆疊指標,當要把資料放到記憶體時,會參考這個值來當作要放在記憶體的哪個位址。

再來要說明的是程式在存放記憶體的位址,基本上是從高位址往低位址放(水往低處流)
這個觀念很重要,當程式在初始化並開始放資料時,一定會從高的位址開始往下放,也就是說當你有新的資料要繼續放的時候,是往低的位址繼續放,除非你知道之前較高的位址裡面的資料你要做變更,否則請不要隨便更改本來位指高的裡面的資料。

組合語言的說明:
在從cvSize的C程式語法裡面知道二點,
1.有兩個int型態width及height,表示儲存時會需要有2*4bytes
2.程式為了自動對齊又多了8bytes,對齊時裡面存放的值是0x000000ff
所以總共需要16bytes
這就是為什麼會有個指令是
sub $0x10,%esp
的由來 0x10 = 16

開始說明組合語言:
0x00436760 push %ebp
這組語是把現在的基底位址儲存起來,請注意一開始esp的位址是0x28fdcc,裡面的值是0xb53d4000這個值就是到時候要retuen時的位址
在執行完這個指令後esp的位址會變成0x28fdc8
高位址cc變成c8,而位址0x28fdc8會儲存ebp的值,
但儲存的順序是從low byte到hight byte,也就是反過來儲存,
所以本來ebp的位址0x28fdf8就會變成這樣 f8 fd 28 00
0x28fdcf 00
0x28fdce 40
0x28fdcd 3d
0x28fdcc b5
0x28fdcb 00
0x28fdca 28
0x28fdc9 fd
0x28fdc8 f8
   .
   .
   .
   .

0x00436761 mov %esp,%ebp
將esp的值放到ebp裡面,把堆疊指標的值先存放基底指標
這邊要說明一下,如果用現在這個例子來看的話,前面這兩個指令其實看不出作用
但是如果cvSize這個函數裡面又呼叫(call)另外一個函數時,這就是重點了!!!
這樣基底指標跟堆疊指標才不會亂掉

0x00436763 sub $0x10,%esp
這個地方前面有先說明0x10的由來
這邊把esp內的值減0x10,是為了給出這個函數用的資料空間,也就是從
0x28fdc8 到0x28fdb8都空出來留給cvSize使用,
此時esp = 0x28fdb8
此時ebp = 0x28fdc8
在這個邊界內的資料都是屬於cvSize的
這個0x10的值在程式編譯時就會根據程式內容來宣告該給予多少的資料空間,
所以不同的函數在這個地方會特別的不一樣!!!!
而留出來的空間,在未使用時,程式預設會給的值是0x00000000,但也有可能不同!!!
此時記憶體的資料應該是像這樣

0x28fdc7 00
0x28fdc6 00
0x28fdc5 00
0x28fdc4 00
0x28fdc3 00
0x28fdc2 00
0x28fdc1 00
0x28fdc0 00
0x28fdbf 00
0x28fdbe 00
0x28fdbd 00
0x28fdbc 00
0x28fdbb 00
0x28fdba 00
0x28fdb9 00
0x28fdb8 00

0x00436766 mov    0x8(%ebp),%eax
這邊就是把剛剛說的width = 0x81(129)的值放到eax
因為width的資料位址是0x28fdd0
而ebp現在的位址是0x28fdc8
所以是ebp的位址 + 0x8 沒錯。
這邊忘記說明一點,
在組合語言裡面通常是利用ebp的位址指標來存取相對位址的資料內容的
所以會常看到ebp這個基底指標

0x00436769 mov    %eax,-0x8(%ebp)
把剛剛eax的值放到ebp - 0x8的位址上(0x28fdc0),
從這邊開始資料位址就開始坐落在cvSize的資料空間(0x28fdc8 到0x28fdb8)

0x0043676C mov    0xc(%ebp),%eax
這邊是把height = 0x15(21)的值放到eax

0x0043676F mov    %eax,-0x4(%ebp)
把剛剛eax的值放到ebp - 0x4的位址上(0x28fdc4),
一樣坐落在cvSize的資料空間(0x28fdc8 到0x28fdb8)

0x00436772 mov    -0x8(%ebp),%eax
把剛剛儲存在0x28fdc0的值放到eax

0x00436775 mov    -0x4(%ebp),%edx
把剛剛儲存在0x28fdc4的值放到edx

0x00436778 leave
還沒執行這個值指令時
esp = 0x28fdb8
ebp0x28fdc8
執行leave後,會先將ebp+0x4這個位址的值放到esp,然後把目前ebp位址的値放到ebp中,
簡單講就是執行pop指令把記憶體中的值取下來放到ebp,
執行後
esp = 0x28fdcc(ebp+0x4)
ebp = 0x28fdf8

0x28fdcb 00
0x28fdca 28
0x28fdc9 fd
0x28fdc8 f8

0x00436779 ret
返回原本呼叫cvSize的程式位置
也就是pop esp位址的資料後
jump回去原本的程式位置可以看下圖eip的值為0x00403db5

0x28fdcf 00
0x28fdce 40
0x28fdcd 3d
0x28fdcc b5

回到成是最後的畫面是這樣


在剛剛返回前已經把
s.width = 129
s.height = 21
放到暫存器eax和edx了!!!

2015年6月15日 星期一

Line Number Test

從這邊學來的~~
http://eric0806.blogspot.tw/2014/04/blogger-google-code-prettify.html
感謝老宅大大~~

以後寫Code在Blog可以有 Line Number了!!!!
請編輯時切換到HTML模式,打下面兩個紅字,藍色是要放的程式碼~~
<pre>
要放的Code
</pre>




# Python 3: Simple output (with Unicode)
>>> print("Hello, I'm Python!")
Hello, I'm Python!

# Input, assignment
>>> name = input('What is your name?\n')
>>> print('Hi, %s.' % name)
What is your name?
Python
Hi, Python.

創用 CC 授權條款
我什麼都不會!!Eddie Sung製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款釋出。
此作品衍生自Eddie Sung