关于上次那道考研题的补充
wingc 2001-06-09 03:37:00 详情请见
http://www.csdn.net/expert/topic/142/142139.shtm
上次那道考研题,多亏了各位高手的指导,小弟得以了解了其中玄机,呵呵,特别是edyang(石头)大侠和azuo_lee()大侠,但是小弟这几日自己琢磨一番后,发现azuo_lee()后来的补充有问题,所以特别补充一下。
这是那日用azuo_lee()这个ID的大侠的回答
^^
执行printf时系统堆栈应为:
————
返回cs <——————仅在大模式时有效,Win32中此项不存在。
————
返回ip
————
10
————
char *
————
所以我觉得printf应分别输出10、返回地址的ip、随机数或返回的cs。
小弟用tc将源代码编译成汇编后发现汇编源程序如下:
ifndef ??version
?debug macro
endm
endif
?debug S "test.c"
_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP,ss:DGROUP
_TEXT ends
_DATA segment word public 'DATA'
d@ label byte
d@w label word
_DATA ends
_BSS segment word public 'BSS'
b@ label byte
b@w label word
?debug C E92094BB2806746573742E63
_BSS ends
_TEXT segment byte public 'CODE'
; ?debug L 1
_main proc near
; ?debug L 2
mov ax,10
push ax
mov ax,offset DGROUP:s@
push ax
call near ptr _printf
pop cx
pop cx
@1:
; ?debug L 3
ret
_main endp
_TEXT ends
?debug C E9
_DATA segment word public 'DATA'
s@ label byte
db 37
db 100
db 44
db 32
db 37
db 100
db 44
db 32
db 37
db 100
db 10
db 0
_DATA ends
_TEXT segment byte public 'CODE'
extrn _printf:near
_TEXT ends
public _main
end
上面代码证明了edyang(石头)说得对,入栈顺序是从右至左,10先push进去,然后push了一个label,这个label是输出格式"%d,%d,%d"的地址,大家应该可以看得出来%的ascii码就是37,库里的_printf函数应该先从栈中读出这个label,知道如何输出后,再从栈中得到10来输出,这时要再输出时应该sp指向先与10亚入的数据,而cs:ip是在压用那个label后再压入的,不是先与10亚入的。所以小弟认为那天用azuo_lee()这个id大侠的回答不大正确,但小弟学道尚浅,不知以上分析对否,望各位大侠指教。
还有不知如何让gcc编译输出汇编代码,望各位大侠告知。小弟想看看gcc编译出来的又有何不同,原题不是要考考不同平台吗,呵呵。