我們將六個Helloworld!順利的輸出完成了,接下來就是程式要進行結束時的動作了,我們來看最後的程式碼。
可以發現GDB明顯的比較少,在MOV後只做了leave就Return了,但其實leave只是一個縮寫,leave其實等於
MOV RSP,RBP
POP RBP
這兩行動作,這邊順便說一下,有時候在程式最一開始的時候會出現enter,而這個enter的意思表示
PUSH RBP
MOV RBP,RSP
SUB RSP,xxx
這其實等同於我們最一開始說的分配空間。
接下來我們一行一行來看,首先是MOV EAX,0,為什麼要將EAX內的值歸0呢,這其實又是Calling conventions規定的,在程式要結束時,我們會需要返回0,來讓程式知道說,我們這個程式運作順暢,沒有任何錯誤的結束,如果最後返回的不是0,那就可能代表程式出現錯誤了,因此根據Calling conventions的規定,在程式的最後需要將EAX的值設為0。
接著在IDA中是ADD RSP,30h,這很好理解,根據最一開始的SUB RSP,30h,這只是把RSP放回原來的位置而已,而在GDB當中的leave也是做一樣的事,只是可能是做MOV RSP,RBP,但兩者是相同的,因為RBP指的是最底端,都是將RSP原本有的空間給釋放掉。
從IDA來看,BF0+30h=C20
從GDB來看,70+0x10=80
最後是POP RBP,這不管是IDA或GDB都是做一樣的事情,將上一個程式的RBP給丟回去,讓上一支程式的RBP歸位。
至此,就完整的結束了一個Print "Helloworld!" 6次的小程式。