可見,函數的返回值為結構體類型,其返回值既不是“值傳遞”也不是通過“寄存器”回傳。編譯器在編譯此類函數時,為其附加了一個指針參數(指向的地址在caller的堆棧上),且作為函數的第一個參數(函數本身的參數依次后移),函數語義上的返回值通過該附加的指針參數回傳,而函數真正的返回值就是該指針。
————————————————版權聲明:本文為CSDN博主「stillvxx」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/stillvxx/article/details/41409949
我們知道,函數一般通過ret指令返回。因為call指令暗含了“將函數的返回地址入棧的操作”,因此對應的ret指令暗含了“彈出函數返回地址的操作”,這一入棧、一彈出棧就平衡了。但div()函數卻是通過“retn 4”返回,即在“彈出函數的返回地址”之后又彈出4個字節,將div()函數的第一個參數即附加的參數也彈出了。至於為什么要這么干,注釋中的說明有些戲虐的成分,應該是與調用規范有關。總之,通過“retn 4”返回到caller中(testdiv()函數中),由於多執行一次“出棧”操作,導致caller的棧不平衡了,因此在caller中通過“sub esp,4”又將堆棧擴展4個字節,恢復棧平衡。
————————————————
版權聲明:本文為CSDN博主「stillvxx」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/stillvxx/article/details/41409949