²Ä¤C³¹¡@°ïÅ|®Ø¡]¤G¡^

«e¤@³¹¤w¸g§â GCD.ASM ·|¥Î¨ì¦ý¥¼´¿´£¹Lªº x64 «ü¥O¡BWin64 API ¤¶²Ð§¹²¦¡A³o¤@³¹´N­n¶i¤J¥DÃD¡A»¡©ú°ïÅ|®Ø¤F¡C


°ïÅ|®Ø¬O¤°»ò

¦p¦P«e¤@³¹©Ò­z¡A°ïÅ|®Ø¬OÀ³¥Îµ{¦¡©I¥s°Æµ{¦¡®É¡A¦p¦³¥²­n·|¦b°ïÅ|¤W«Ø¥ß¤@¶ô°O¾ÐÅéªÅ¶¡¡A¨Ñ¨ä°õ¦æ´Á¶¡¨Ï¥Î¡C³o¶ôªÅ¶¡³q±`¥]§tªð¦^¦ì§}¡B©I¥sªÌª¬ºA¡]¦p­ì¥ýªº RBP ©Î³Q«O¦sªº¼È¦s¾¹¡^¡B°Æµ{¦¡©Ò»Ýªº°Ï°ìÅܼƥH¤Î»P¬ÛÃöªº¸ê®Æ¡A³o¼Ëªº°O¾ÐÅéªÅ¶¡ºÙ¬°°ïÅ|®Ø¡]stack frame¡^¡C

·íÀ³¥Îµ{¦¡°õ¦æ CALL «ü¥O®É¡A«Ø¥ßªº°ïÅ|®Ø¥²¶·¿í´` x64 ©I¥sºD¨Ò¡C©Ò¥H RSP ©Ò«üªº°ïÅ|¦ì§}¥²¶·¯à³Q 10h ¾ã°£¡A§_«hÀ³¥Îµ{¦¡·|·í±¼¡C¦]¦¹·í CALL «ü¥O§âªð¦^¦ì§}±À¤J°ïÅ|®É¡A«O¦sªð¦^¦ì§}ªº°ïÅ|¦ì§}¤§­Ó¦ì¼Æ¥²¬° 8¡A¦p¥k¹Ïªº HIJKY8¡C¡]H¡BI¡BJ¡BK¡BY ¦U¥Nªí¤Q¤»¶i¦ìªº¤@¦ì¼Æ¡A±q 0 ¨ì F¡^

¶i¤J°Æµ{¦¡«á¡A²Õ;¹·|¨Ì¾Ú PROC¡BLOCAL µ¥°²«ü¥O¡A§¹¦¨©³¤U¨Æ±¡¡G

⑴¡B±N RBP ±À¤J°ïÅ|«O¦s°_¨Ó¡AµM«á§â RSP ¤§­È½á¤© RBP¡C¦p¤Uµ{¦¡¡G

        push    rbp
        mov     rbp,rsp

¬°¦ó­n°õ¦æ³o¨â¹D«ü¥O©O¡H³o¬O¦]¬°¦b°Æµ{¦¡¸Ì¡A­n¥Î RBP §@¬°°ò·Ç¡A¥h¦s¨ú°Ï°ìÅܼƩΰѼơC

⑵¡B²Õ;¹¨Ì¾Ú LOCAL ©Ò©w¸qªº°Ï°ìÅܼƪº¦h¹è¡A±N°ïÅ|ªÅ¥X¤@¶ô°Ï°ì¡A§@¬°®e¯Ç°Ï°ìÅܼơC¤èªk«Ü²³æ¡A¨Ï RSP ´î¥h°Ï°ìÅܼƩһݪºªÅ¶¡¡C¡]¨£¥k¹Ï°Ï°ìÅܼƤ@¡ãN¡^

⑶¡B²Õ;¹¨Ì¾Ú PROC ªº USES ¼È¦s¾¹¦Cªí¡A±N³o¨Ç¼È¦s¾¹±À¤J°ïÅ|³Æ¥÷°_¨Ó¡C¦]¬°°Æµ{¦¡°õ¦æ¹Lµ{¤¤¡A·|¨Ï¥Î¨ì¬Y¨Ç¼È¦s¾¹¡AÁ×§Kªð¦^¥Dµ{¦¡®É§ïÅܳo¨Ç¼È¦s¾¹¡A¬G±N¨ä«O¦s¡A«Ýªð¦^¤§«e¡]¤]´N¬O²Ä⑸¨BÆJ¡^«ì´_­ì­È¡C³o¨Ç¼È¦s¾¹´N¬O«e­±»¡ªº«D´§µo©Ê¼È¦s¾¹¡A¥¦­Ì¥i¥H«O¦s¦b¥k¹Ï¼Ð¥Ü¼È¦s¾¹¤@¡ãN¡C

⑷¡B¦b°Æµ{¦¡¤§¤º¡A¤]¦³¥i¯à¤]·|©I¥s§Oªº°Æµ{¦¡©Î¬O Win64 API¡C©Ò¥H±µ¤U¨Ó¥²¶·½Õ¾ã RSP ¤§­È¡A¦¹¥Øªº¦³¤G¡G①¨Ï¨ä¯à®e¯Ç§Oªº°Æµ{¦¡¤§¼v¤lªÅ¶¡¥H¤Î§ó¦h°Ñ¼Æ¡]¦pªG¦³ªº¸Ü¡^¡A②¨Ã¥B©I¥s§Oªº°Æµ{¦¡©Î Win64 API ®É¡A°ïÅ|³»ºÝ¯à¹ï»ô¸`¦ì§}¡C½Õ¾ã¤è¦¡«Ü²³æ¡A§â RSP ´î¥h¤@¼Æ¡A¨Ï¨ä­Ó¦ì¼ÆÅܬ°¹s¡C¨£¥k¹Ï¹ï»ôªÅ¶¡¡ãRCX¡C

⑸¡B°h¥X°Æµ{¦¡®É¡A¥²¶·¥ý¨Ï RSP ¥[¤W­è­è´î¥hªº¼Æ¡A¨Ï¨ä«ì´_½Õ¾ã«e¤§­È¡C¥H²Å¦X x64 ©I¥sºD¨Ò¡A©I¥sªÌ­t³d²M²z°ïÅ|¡C

⑹¡B²Õ;¹·|¦b°Æµ{¦¡µ²§ô¤§«e¡A¤]´N¬O¦b¸Ó°Æµ{¦¡¤§¤¤ªº RET «ü¥O¤§«e¡A¨Ì¾Ú PROC ªº USES ¼È¦s¾¹¦Cªíªº¤Ï¦V¶¶§Ç¡A±N­ì¨Ó¼È¦s¾¹¤§­È¥Ñ°ïÅ|¤¤¼u¥X¡A³Ì«á¦A¥[¤W LEAVE «ü¥O«ì´_ RBP »P RSP ¤§­È¡C­nª`·Nªº¬O¡A¦pªG°Æµ{¦¡¤¤¤£¥u¤@­Ó RET¡A¨º»ò²Õ;¹·|¦b¨C­Ó RET ¤§«e«ì´_­ì¼È¦s¾¹¤§­È¡A¤Î¥[¤W LEAVE «ü¥O¡C

¤W­±ªº¤­­Ó¨BÆJ¤¤¡A¥u¦³²Ä⑷¡B⑸¨â­Ó¨BÆJ¥²¶·¬Oµ{¦¡³]­p®v¦Û¦æ­pºâ¡A¨ä¾lªº³£¬O²Õ;¹¦Û°Ê²K¥[ªº¡CÁA¸Ñ¤F°ïÅ|®Ø¤§«á¡A©³¤U¨Ó¬Ý¬ÝÀ³¥Îµ{¦¡¬O¦p¦ó¹ê²{°ïÅ|®Ø¡A¥H²Å¦X x64 ©I¥sºD¨Ò¡C


GCD.ASM ­ì©lµ{¦¡

¤p¤ì°¸¨Ï¥Î GCD.ASM ¨Ó»¡©ú¦p¦ó¨Ï¥Î°ïÅ|®Ø¡CGCD ¥iÅý¨Ï¥ÎªÌ¿é¤J¨â­Ó¥¿¾ã¼Æ¡AµM«á­pºâ¥¦­Ìªº³Ì¤j¤½¦]¼Æ¡A¨Ã¦L¦b¿Ã¹õ¤W¡A¥þ³¡­ì©l½X¦p¤U¡G

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
OPTION CASEMAP:NONE
EXTRN  GetStdHandle:PROC,CloseHandle:PROC,ExitProcess:PROC
EXTRN  StrToIntA:PROC,wsprintfA:PROC,WriteConsoleA:PROC,ReadConsoleA:PROC
INCLUDELIB E:\masm64\lib64\kernel32.lib
INCLUDELIB E:\masm64\lib64\user32.lib
INCLUDELIB E:\masm64\lib64\shlwapi.lib
one_hundred_million EQU 100000000 ;¤@»õ=5F5E100h
;******************************************************************************
.DATA
hInput  DQ      ?       ;¼Ð·Ç¿é¤J¸Ë¸m±±¨î¥N½X
hOutput DQ      ?       ;¼Ð·Ç¿é¥X¸Ë¸m±±¨î¥N½X
n1      DD      ?       ;¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È1
n2      DD      ?       ;¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È2
gcd     DD      ?       ;n1¡Bn2ªº³Ì¤j¤½¦]¼Æ
szGcd   DB      52 DUP (0)
sHint   DB      "½Ð¿é¤J¤£¤j©ó¤@»õªº¥¿¾ã¼Æ¡G"
sErr1   DB      "±z¿é¤J¤j©ó¤@»õªº¼Æ¡I"
sErr2   DB      "¿é¤J¿ù»~©Î¿é¤J¹s¡I"
szFmt   DB      "%d¡B%dªº³Ì¤j¤½¦]¼Æ¬O%d¡C",0
;******************************************************************************
.CODE
;------------------------------------------------------------------------------
Input   PROC    USES rbx rsi rdi hIn:QWORD,hOut:QWORD,pNumber:QWORD
;¿é¤J¡GhIn¡BhOut¡Ð¼Ð·Ç¿é¤J¡B¿é¥X¸Ë¸m±±¨î¥N½X
;¡@¡@¡@pNumber¡Ð¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦s©ñ¦ì§}
;¿é¥X¡GRAX¡×0¡A¿é¤J¿ù»~
;¡@¡@¡@RAX¡×1¡A¿é¤J¥¿½T¡ApNumber©Ò«ü¦ì§}¦s¦³¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È
        LOCAL   nWritn:DWORD,nRead:DWORD,buffer[12]:BYTE
        sub     rsp,30h
    ;§â°Ñ¼Æ¦s¤J¼v¤lªÅ¶¡
        mov     hIn,rcx
        mov     hOut,rdx
        mov     rbx,r8
    ;invoke WriteConsoleA,hOut,ADDR sHint,SIZEOF sHint,ADDR nWrtin,0¡]¦L¥XsHint¦r¦ê¡^
        mov     rcx,hOut
        mov     rdx,OFFSET sHint
        mov     r8,SIZEOF sHint
        lea     r9,nWritn
        mov     QWORD PTR [rsp+20h],0
        call    WriteConsoleA
    ;invoke ReadConsoleA,hIn,ADDR buffer,ADDR nRead,0¡]Åý¨Ï¥ÎªÌ¿é¤J¼Æ­È¦r¦ê¡^
        mov     rcx,hIn
        lea     rdx,buffer
        mov     r8,SIZEOF buffer
        lea     r9,nRead
        mov     QWORD PTR [rsp+20h],0
        call    ReadConsoleA
    ;invoke StrToIntA,ADDR buffer¡]§â¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦r¦êÂà´«¦¨¼Æ­È¡^
        lea     rcx,buffer
        call    StrToIntA
    ;Àˬd¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¬O§_¶W¹L¤Q»õ
        cmp     eax,one_hundred_million
        jbe     chk_zr
        lea     rdx,sErr1       ;­Y¶W¹L¦L¥XsErr1
        mov     r8,SIZEOF sErr1
        jmp     pnt_it
chk_zr: test    eax,eax         ;­Y¥¼¶W¹L¡A¦AÀˬd¬O§_¬°¹s
        jnz     ok              ;­Y¤£¬°¹s¡A¸õ¦Üok
        lea     rdx,sErr2       ;­Y¬°¹s¡A¦L¥XsErr2
        mov     r8,SIZEOF sErr2
    ;invoke WriteConsoleA,hOut,rdx,r8d,ADDR nWritn,0¡]¦L¥XsErr1©ÎsErr2ªº¿ù»~°T®§¡^
pnt_it: mov     rcx,hOut
        lea     r9,nWritn
        mov     QWORD PTR [rsp+20h],0
        call    WriteConsoleA
    ;¨ÏRAXÅܬ°¹s¡A¨ÃÂ÷¶}Input
        xor     rax,rax
        jmp     quit
    ;¨Ï¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦s¤JpNumber©Ò«ü¦ì§}
ok:     mov     [rbx],eax
quit:   add     rsp,30h
        ret
Input   ENDP
;------------------------------------------------------------------------------
FindGcd PROC    num1:DWORD,num2:DWORD
;¿é¤J¡Gnum1¡Bnum2¨â­Ó¾ã¼Æ
;¿é¥X¡GEAX¡×³Ì¤j¤½¦]¼Æ
again:  xchg    ecx,edx ;¾l¼ÆÅܬ°¤U¦¸ªº°£¼Æ¡A­ì¨Óªº°£¼ÆÅܳQ°£¼Æ
        mov     eax,edx
        cdq
        div     ecx     ;¨ÏEDX:EAX¡]³Q°£¼Æ¡^°£¥HECX¡]°£¼Æ¡^
        or      edx,edx ;¾l¼Æ¬°EDX
        jnz     again   ;­YEDX¬°¹s¡A³Ì«á¤@¦¸ªº°£¼Æ§Y¬°GCD
        mov     eax,ecx ;§â³Ì¤j¤½¦]¼Æ¦s¤JRAX
        cdqe
        ret
FindGcd ENDP
;------------------------------------------------------------------------------
main    PROC
        sub     rsp,28h
    ;¨ú±o¼Ð·Ç¿é¤J¡B¿é¥X¸Ë¸mªº±±¨î¥N½X
        mov     rcx,-10 ;STD_INPUT_HANDLE=-10
        call    GetStdHandle
        mov     hInput,rax
        mov     rcx,-11 ;STD_OUTPUT_HANDLE=-11
        call    GetStdHandle
        mov     hOutput,rax
    ;invoke Input,hInput,hOutput,ADDR n1¡]¿é¤J²Ä¤@­Ó¥¿¾ã¼Æ¡^
        mov     rcx,hInput
        mov     rdx,hOutput
        mov     r8,OFFSET n1
        call    Input
        or      eax,eax
        jz      error
    ;invoke Input,hInput,hOutput,ADDR n2¡]¿é¤J²Ä¤G­Ó¥¿¾ã¼Æ¡^
        mov     rcx,hInput
        mov     rdx,hOutput
        mov     r8,OFFSET n2
        call    Input
        or      eax,eax
        jz      error
    ;invoke FindGcd,n1,n2¡]­pºân1¡Bn2ªº³Ì¤j¤½¦]¼Æ¡^
        mov     ecx,n1
        mov     edx,n2
        call    FindGcd
    ;invoke wsprintfA,ADDR szGcd,ADDR szFmt,n1,n2,eax¡]¥Í¦¨szGcd¦r¦ê¡^
        mov     rcx,OFFSET szGcd
        mov     rdx,OFFSET szFmt
        mov     r8d,n1
        mov     r9d,n2
        mov     [rsp+20h],eax
        call    wsprintfA
    ;invoke WriteConsoleA,hOutput,ADDR szGcd,eax,0,0¡]¦L¥XszGcd¦r¦ê¡^
        mov     rcx,hOutput
        lea     rdx,szGcd
        mov     r8d,eax
        xor     r9,r9
        mov     QWORD PTR [rsp+20h],0
        call    WriteConsoleA
    ;invoke ExitProcess,0¡]Â÷¶}GCD.EXE¡^
error:  xor     rcx,rcx
        call    ExitProcess
main    ENDP
;******************************************************************************
END

±N¤W­z­ì©lµ{¦¡Àx¦s¦b¡uE:\HomePage\SOURCE\Win64\CONSOLE\GCD.ASM¡v¡AµM«á¨Ì·Ó¤U­±¨BÆJ²ÕĶ¡B³sµ²¡A¥u»Ý­n¿é¤J©³¤U¶À¦â¦r§Y¥i±o¨ì GCD.EXE¡C¥¦¬O¬O±±¨î»Oµ{¦¡¡A¥i¥H¦b©R¥O´£¥Ü¦r¤¸¤¤°õ¦æ¡A¿é¤J GCD §Y¥i°õ¦æ¡]¨£¤U­±³Ì«á¤@­Ó¶À¦rªº«ü¥O¡^¡A·íµM¿é¤J¨â¥¿¾ã¼Æ®É¡A¥i¥H¿é¤J¥ô¦ó¤£¤j©ó¤@»õªº¥¿¾ã¼Æ³£¡A¤£¥²¤@©w­n¬O 655360 ©Î 458400¡G

C:\Users\wanker>cd e:\HomePage\SOURCE\Win64\CONSOLE

C:\Users\wanker>e:

e:\HomePage\SOURCE\Win64\CONSOLE>ml64 gcd.asm /link /subsystem:console
Microsoft (R) Macro Assembler (x64) Version 14.25.28614.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 Assembling: gcd.asm
Microsoft (R) Incremental Linker Version 14.25.28614.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/subsystem:windows /entry:main
/OUT:gcd.exe
gcd.obj
/subsystem:console

e:\HomePage\SOURCE\Win64\CONSOLE>gcd
½Ð¿é¤J¤£¤j©ó¤@»õªº¥¿¾ã¼Æ¡G655360
½Ð¿é¤J¤£¤j©ó¤@»õªº¥¿¾ã¼Æ¡G458400
655360¡B458400ªº³Ì¤j¤½¦]¼Æ¬O160¡C
e:\HomePage\SOURCE\Win64\CONSOLE>

¸ÑªR GCD.ASM

µy·LÆ[¹î´N¯àµo²{¨â¥ó¨Æ¡G①GCD.ASM §¹¥þ¤£¥Î MASM64 SDK¡A¦Ó¬O¡u¯Â¤â¤u¡v¥´³y¡A¬°¤°»ò³o¼Ë°µ©O¡H«e¤@³¹¤w¦³»¡©ú¡C②GCD.ASM ªºµ²ºc¬O¤@­Ó¥Dµ{¦¡¡]main¡^¤Î¥Ñ¨â­Ó°Æµ{¦¡¡]Input¡BFindGcd¡^©Ò²Õ¦¨¡C

main ­t³dÀò¨ú¼Ð·Ç¿é¥X¡þ¿é¤J¸Ë¸m±±¨î¥N½X¡F¨Ã©I¥s¨â¦¸ Input °Æµ{¦¡¡A¥H«KÅý¨Ï¥ÎªÌ¿é¤J¨â­Ó¥¿¾ã¼Æ¡F³Ì«á´N¬O©I¥s FindGcd °Æµ{¦¡¨D¥X¨â¼Æªº³Ì¤j¤½¦]¼Æ¡A¦A©ó¿Ã¹õ¤W¦L¥X¨Ó¡Cmain ¤º¨Ã¨S¦³½ÆÂøªº¬yµ{°ÝÃD¡A¦Ó¦³Ãö FindGcd ªº­ì²z¦b«e¤@³¹¤w¸g»¡©ú¹L¤F¡A©Ò¥H³o¨â­Ó¥DÃD³£¤£°Q½×¡C³o¤@³¹ªº­«ÂI¦b©óÂǥѭåªR Input¡BFindGcd ¨â­Ó°Æµ{¦¡¡A¶i¦ÓÁA¸Ñ°ïÅ|®Øªº¬[ºc¡C

²Õ;¹§ïÅܤF­ì©lµ{¦¡¤°»ò¡H

¦pªG¥Î x64dbg ¸ü¤J GCD.EXE ¨ÃÆ[¹î Input¡BFindGcd °Æµ{¦¡¡A§A·|µo²{²Õ;¹¡]³o¸Ì«üªº¬O ML64.EXE¡^·|²K¥[¤@¨Ç«ü¥O¡C¦]¬° FindGcd ¤£²o¯A°Ï°ìÅܼƩM³Æ¥÷¼È¦s¾¹¡A¥ý¨ÓÆ[¹î¥¦¦³¦óÅܤơC ¤ñ¸û²³æ¤Uªí¬O¥ªÄæ¬O­ì©lµ{¦¡¡A¥kÄæ¬O²ÕĶ«áªºµ{¦¡½X¡G

­ì©lµ{¦¡²ÕĶ«áªº­ì©l½X
FindGcd PROC    num1:DWORD,num2:DWORD
;¿é¤J¡Gnum1¡Bnum2¨â­Ó¾ã¼Æ
;¿é¥X¡GEAX¡×³Ì¤j¤½¦]¼Æ
again:  xchg    ecx,edx ;¾l¼ÆÅܬ°¤U¦¸ªº°£¼Æ¡A­ì¨Óªº°£¼ÆÅܳQ°£¼Æ
        mov     eax,edx
        cdq
        div     ecx     ;¨ÏEDX:EAX¡]³Q°£¼Æ¡^°£¥HECX¡]°£¼Æ¡^
        or      edx,edx ;¾l¼Æ¬°EDX
        jnz     again   ;­YEDX¬°¹s¡A³Ì«á¤@¦¸ªº°£¼Æ§Y¬°GCD
        mov     eax,ecx ;§â³Ì¤j¤½¦]¼Æ¦s¤JRAX
        cdqe
        ret
FindGcd ENDP
    push rbp
    mov  rbp,rsp
@@: xchg edx,ecx
    mov  eax,edx
    cdq
    div  ecx
    or   edx,edx
    jne  @b
    mov  eax,ecx
    cdqe
    leave
    ret

¤ñ¸û¨âÃ䤧«á¡A·í¥iµo²{¡A²Õ;¹²K¥[¤F¥Õ¦â¼Ð¥Üªº¨â¹D«ü¥O¡]¦b¤Wªí¥kÄæ¡^¡C¦]¬° FindGcd ¥u¬O²³æªº¹Bºâ¦Ó¤w¡A¨Ï¥Î RAX¡BRCX¡BRDX ´N¤w¸g¨¬°÷¡A©Ò¥H¨ä¹ê²K¥[ªº³o¨â¹D«ü¥O¨ÃµL¥Î³~¡C¤£¹L±q³o¨à¥iª¾¡A¤£½×¦³¨S¦³¥Î³~¡A²Õ;¹¨£¨ì PROC °²«ü¥O«á¡A·|¦Û°Ê²K¥[³o¨â¹D«ü¥O¡A§@¬°«á­±°ïÅ|®Øªº·Ç³Æ¤u§@¡AÁa¨Ï¨S¥Î³~¡C

¦A¨Ó¬Ý¬Ý Input ²ÕĶ«e«áªº®t§O¡A¨£¤Uªí¡C¥ªÄæ¬O Input °Æµ{¦¡ªº­ì©l½X¡A¥kÄæ«h¬O¦b x64dbg ¸ü¤J«á¥i°õ¦æÀÉ GCD.EXE¡AÅã¥Ü Input µ{¦¡½Xªºµ²ªG¡C·íµM x64dbg ¨Ã¤£·|Åã¥Üµù¸Ñ¡A¨º¬O¤p¤ì°¸¥[¤W¥hªº¡A«K©óÆ[¹î¨âªÌ¤£¦P¡C

­ì©lµ{¦¡²ÕĶ«áªº­ì©l½X
Input   PROC  USES rbx rsi rdi hIn:QWORD,hOut:QWORD,pNumber:QWORD
;¿é¤J¡GhIn¡BhOut¡Ð¼Ð·Ç¿é¤J¡B¿é¥X¸Ë¸m±±¨î¥N½X
;¡@¡@¡@pNumber¡Ð¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦s©ñ¦ì§}
;¿é¥X¡GRAX¡×0¡A¿é¤J¿ù»~
;¡@¡@¡@RAX¡×1¡A¿é¤J¥¿½T¡ApNumber©Ò«ü¦ì§}¦s¦³¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È
        LOCAL   nWritn:DWORD,nRead:DWORD,buffer[12]:BYTE
        sub     rsp,30h
;§â°Ñ¼Æ¦s¤J¼v¤lªÅ¶¡
        mov     hIn,rcx
        mov     hOut,rdx
        mov     rbx,r8
;invoke WriteConsoleA,hOut,ADDR sHint,SIZEOF sHint,ADDR nWrtin,0
;¡]¦L¥XsHint¦r¦ê¡^
        mov     rcx,hOut
        mov     rdx,OFFSET sHint
        mov     r8,SIZEOF sHint
        lea     r9,nWritn
        mov     QWORD PTR [rsp+20h],0
        call    WriteConsoleA
;invoke ReadConsoleA,hIn,ADDR buffer,ADDR nRead,0
;¡]Åý¨Ï¥ÎªÌ¿é¤J¼Æ­È¦r¦ê¡^
        mov     rcx,hIn
        lea     rdx,buffer
        mov     r8,SIZEOF buffer
        lea     r9,nRead
        mov     QWORD PTR [rsp+20h],0
        call    ReadConsoleA
;invoke StrToIntA,ADDR buffer¡]§â¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦r¦êÂà´«¦¨¼Æ­È¡^
        lea     rcx,buffer
        call    StrToIntA
;Àˬd¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¬O§_¶W¹L¤Q»õ
        cmp     eax,one_hundred_million
        jbe     chk_zr
        lea     rdx,sErr1       ;­Y¶W¹L¦L¥XsErr1
        mov     r8,SIZEOF sErr1
        jmp     pnt_it
chk_zr: test    eax,eax         ;­Y¥¼¶W¹L¡A¦AÀˬd¬O§_¬°¹s
        jnz     ok              ;­Y¤£¬°¹s¡A¸õ¦Üok
        lea     rdx,sErr2       ;­Y¬°¹s¡A¦L¥XsErr2
        mov     r8,SIZEOF sErr2
;invoke WriteConsoleA,hOut,rdx,r8d,ADDR nWritn,0
;¡]¦L¥XsErr1©ÎsErr2ªº¿ù»~°T®§¡^
pnt_it: mov     rcx,hOut
        lea     r9,nWritn
        mov     QWORD PTR [rsp+20h],0
        call    WriteConsoleA
;¨ÏRAXÅܬ°¹s¡A¨ÃÂ÷¶}Input
        xor     rax,rax
        jmp     quit
;¨Ï¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦s¤JpNumber©Ò«ü¦ì§}
ok:     mov     [rbx],eax
quit:   add     rsp,30h
        ret
Input   ENDP
        push rbp
        mov  rbp,rsp
        add  rsp,FFFFFFFFFFFFFFE8
        push rbx
        push rsi
        push rdi
        sub  rsp,30
;§â°Ñ¼Æ¦s¤J¼v¤lªÅ¶¡
        mov  qword ptr ss:[rbp+10],rcx ;hIn=[RBP+10]
        mov  qword ptr ss:[rbp+18],rdx ;hOut=[RBP+18]
        mov  rbx,r8
;invoke WriteConsoleA,hOut,ADDR sHint,SIZEOF sHint,ADDR nWrtin,0
;¡]¦L¥XsHint¦r¦ê¡^
        mov  rcx,qword ptr ss:[rbp+18]
        mov  rdx,gcd.7FF6D1CB3050
        mov  r8,18
        lea  r9,qword ptr ss:[rbp-4]   ;nWritn=[RBP-4]
        mov  qword ptr ss:[rsp+20],0
        call <JMP.&WriteConsoleA>
;invoke ReadConsoleA,hIn,ADDR buffer,ADDR nRead,0
;¡]Åý¨Ï¥ÎªÌ¿é¤J¼Æ­È¦r¦ê¡^
        mov  rcx,qword ptr ss:[rbp+10]
        lea  rdx,qword ptr ss:[rbp-14] ;buffer=[RBP-14]
        mov  r8,C
        lea  r9,qword ptr ss:[rbp-8]   ;nRead=[RBP-8]
        mov  qword ptr ss:[rsp+20],0
        call <JMP.&ReadConsoleA>
;invoke StrToIntA,ADDR buffer¡]§â¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¦r¦êÂà´«¦¨¼Æ­È¡^
        lea  rcx,qword ptr ss:[rbp-14]
        call <JMP.&StrToIntA>
;Àˬd¨Ï¥ÎªÌ¿é¤Jªº¼Æ­È¬O§_¶W¹L¤Q»õ
        cmp  eax,5F5E100
        jbe  chk_zr
        lea  rdx,qword ptr ds:[7FF6D1CB3068]
        mov  r8,14
        jmp  pnt_it
chk_zr: test eax,eax
        jne  ok
        lea  rdx,qword ptr ds:[7FF6D1CB307C]
        mov  r8,12
;invoke WriteConsoleA,hOut,rdx,r8d,ADDR nWritn,0
;¡]¦L¥XsErr1©ÎsErr2ªº¿ù»~°T®§¡^
pnt_it: mov  rcx,qword ptr ss:[rbp+18]
        lea  r9,qword ptr ss:[rbp-4]
        mov  qword ptr ss:[rsp+20],0
        call <JMP.&WriteConsoleA>
        xor  rax,rax
        jmp  quit
ok:     mov  dword ptr ds:[rbx],eax
quit:   add  rsp,30
        pop  rdi
        pop  rsi
        pop  rbx
        leave
        ret

¤ñ¸û¥ª¥k¨âÄæ´N¯àµo²{¡G①²Ä¤@­Ó°Ñ¼Æ¦b¦ì§} RBP+10h¡]§Y²HÂŦâ¦r¡AhIn¡^¡A²Ä¤G­Ó°Ñ¼Æ¦b¦ì§} RBP+18h¡]§YÂŦâ¦r¡AhOut¡^¡C②²Ä¤@­Ó°Ï°ìÅܼƦb¦ì§} RBP-4¡]¶À¦â¦r¡AnWritn¡^¡A²Ä¤G­Ó°Ï°ìÅܼƦb¦ì§} RBP-8¡]¼á¦â¦r¡AnRead¡^¡A²Ä¤T­Ó°Ï°ìÅܼƦb¦ì§} RBP-14h¡]¬õ¦â¦r¡Abuffer¡^¡C±q³o¨âÂIªºµo²{´N¯à±oª¾¡A²Õ;¹·|§â RBP §@¬°¦s¨ú°ò·ÇÂI¡A¦A¥[¤W¨C­Ó°Ñ¼Æ©Î°Ï°ìÅܼƶZÂ÷¦¹°ò·ÇÂI¤£¦Pªº°¾²¾¦ì§}¡A´N¯à¦s¨ú­Ó§O°Ñ¼Æ©Î°Ï°ìÅܼƤF¡C°ÝÃD¨Ó¤F¡A²Õ;¹¬O«ç»ò¨M©w³o¨Ç°Ñ¼Æ©Î°Ï°ìÅܼƪº¦ì§}©O¡H³o»P²Õ;¹©Ò²K¥[ªº«ü¥O¦³Ãö¡C

©³¤U¥ý¨Ó¬Ý¬Ý³o¨Ç²K¥[ªº«ü¥O¦p¦ó¹B§@¡H½Ð°Ñ¾\¤U¹Ï¡C¹Ï¤@¬O¦b main §Y±N©I¥s Input °Æµ{¦¡®É°ïÅ|ªº±¡§Î¡A°ïÅ|³»ºÝ¡ARSP «ü¦V¦ì§} 1FFA60¡A²Å¦X­Ó¦ì¼Æ¬O 0¡A¤]´N¬O¹ï»ô¤@¸`¦ì§}¡CÁöµM Input ¥u¦³¤T­Ó°Ñ¼Æ¡A¦ý§O§Ñ¤F¼v¤lªÅ¶¡¦Ü¤Ö­n¯à«O¦s¥|­Ó°Ñ¼Æ¡A¦P®É¤]¤£­n§Ñ¤F main ·|©I¥s wsprintfA¡BWriteConsoleA¡A¥¦­Ì³£¦³¤­­Ó°Ñ¼Æ¡A¦]¦¹¤]±o¹w¯d²Ä¤­­Ó°Ñ¼ÆªºªÅ¶¡¡C

°õ¦æ¡uCALL Input¡v«á¡A±Nªð¦^¦ì§}±À¤J°ïÅ|¡A¨£¹Ï¤G¡C±µ¤U¨Ó´N¬O²Õ;¹²K¥[ªº¡upush rbp¡v¡B¡umov rbp,rsp¡v¨â¹D«ü¥O¡A°õ¦æ§¹«á°ïÅ|±¡§Î¦p¹Ï¤T¡C³o®É­Ô­ì¨Óªº RBP ¤w«O¦s¦b°ïÅ|¦ì§} 1FFA50 ³B¡A¦Ó¥B RBP¡BRSP ¤§­È³£¬O 1FFA50¡C¦b Input ¤§¤º¦p­n¦s¨ú°Ï°ìÅܼƩΰѼơA³£¥H 1FFA50 ¬°°ò·Ç¡F°£¦¹¤§¥~¡A¦b Input ¤º¡ARBP ¤§­È³£¤£À³§ïÅÜ¡A³o¼Ë°µªº²z¥Ñ¦³¤G¡G①¦pªG§ïÅܦs¨ú°Ï°ìÅܼƩΰѼƴN·|¦³°ÝÃD¡C②±N¨Ó­nªð¦^ main ®É¡A¤£½× RSP §ïÅܦh¤Ö¡A¥u­n°õ¦æ¡umov rsp,rbp¡v´N¯à§ä¨ì¶i¤J Input ®Éªº°ïÅ|³»ºÝ¡A°õ¦æ¡upop rbp¡v´N¯à«ì´_­ì RBP¡F©ÎªÌª½±µ°õ¦æ¡uleave¡v´N¯à¦P®É¹F¦¨¨â¹D«ü¥Oªº¥\¯à¡C

¨ì³o¨à¥i¥H»¡¤@»¡À³¥Îµ{¦¡¬O¦p¦ó¦s¨ú°Ñ¼Æ¡C¬Ý¹Ï¤T¡ARBP ©Ò«ü¦ì§}¬O 1FFA50¡A¦Ó¦b¼v¤lªÅ¶¡¤¤ªº²Ä¤@­Ó°Ñ¼Æ¦b¦ì§} 1FFA60¡B²Ä¤G­Ó°Ñ¼Æ¦b 1FFA68¡K¡K¡A©Ò¥H²Ä¤@­Ó°Ñ¼Æ¦ì§}´N¬O RBP+10¡B²Ä¤G­Ó°Ñ¼Æ¦ì§}¬O RBP+18¡K¡K¡A¬O¤£¬O²Å¦X¤Wªí¤¤¡A¥H²HÂŦâ¡BÂŦâ©Ò¼Ð¥Üªº²Ä¤@¡B¤G­Ó°Ñ¼Æ¦ì§}¡C±µ¤U¨Óªº¡uadd rsp,FFFFFFFFFFFFFFE8¡v¬O²Õ;¹²K¥[ªº«ü¥O¡C¨ä¹ê FFFFFFFFFFFFFFE8h ¬O¦³¸¹¼Æ¡A¬Û·í©ó -18h¡]¥H«á¦A½Í¦³¸¹¼Æ¡^¡C©Ò¥H³o­Ó«ü¥O¬Û·í©ó§â RSP ´î¥h 18h¡A¤]´N¬O´î¥h¤Q¶i¦ìªº 24¡A¥Øªº¬O§â°ïÅ|³»ºÝ©¹¤W²¾ 24 ­Ó¦ì¤¸²ÕªÅ¥X¤@¶ôªÅ¶¡¡A³o¶ôªÅ¶¡¬Oµ¹°Ï°ìÅܼƨϥΪº¡A¨£¤W¹Ï¥|¡C¦b Input ©w¸qªº°Ï°ìÅܼƬO¡G

        LOCAL   nWritn:DWORD,nRead:DWORD,buffer[12]:BYTE

Á`¦@¬O¤G¤Q­Ó¦ì¤¸²Õ¡]4+4+12=20¡^¡C¤£¹L¦b Win64 ¨t²Î¤¤¡A°ïÅ|³»ºÝ¨C¦¸¥u¯à²¾°Ê¤K­Ó¦ì¤¸²Õ¡A©Ò¥H¥u¦n®ö¶O¥|­Ó¦ì¤¸²Õ±Ë±ó¤£¥Î¡C¥Ñ©ó¨Ï¥Î°ïÅ|¬O±q°ª¦ì§}©¹§C¦ì§}©µ¦ù¡A©Ò¥H nWritn ¦ì©ó°ïÅ| 1FFA48¡ã1FFA4F ¸û°ª¦ì§}ªº¥|­Ó¦ì¤¸²Õ¡AnRead «h¦ì©ó¸û§C¦ì§}ªº¥|­Ó¦ì¤¸²Õ¡F¬G nWritn ªº¦ì§}¬O 1FFA4C¡AnRead ªº¦ì§}¬O 1FFA48¡CRBP «ü¦V 1FFA50¡A©Ò¥H nWritn¡BnRead ªº¦ì§}¤À§O¬O RBP-4¡BRBP-8¡]¨£¤Wªí¼Ð¥Üªº¶À¦â»P¾í¦â¦r¡^¡C

±µ¤U¨Ó¬O³sÄò¤T¹D PUSH «ü¥O¡AÅý RBX¡BRSI¡BRDI ¨Ì§Ç±À¤J°ïÅ|«O¦s¨ä­È¡Cx64 ©I¥sºD¨Ò¤¤¡ARBX¡BRSI¡BRDI ÄÝ©ó«D´§µo©Ê¼È¦s¾¹¡A¦pªG°Æµ{¦¡¤º¨Ï¥Î³oÃþ¼È¦s¾¹¡A¨º»ò°Æµ{¦¡¦³¸q°È«O¦s¨ä­È¡A¨Ï¨ä¦b°h¥X°Æµ{¦¡®É¡A¨ä­È¤´¤£ÅÜ¡C¤èªk´N¬O¨Ï¥Î PUSH¡A±N«D´§µo©Ê¼È¦s¾¹«O¦s©ó°ïÅ|ùØ¡CML64.EXE ²Õ;¹´£¨Ñ¤@­Ó²¼äªº¿ìªk¡A§Q¥Î PROC °²«ü¥Oªº USES¡A¥i¥H¦Û°Ê¥Í¦¨±N¼È¦s¾¹ PUSH ¦Ü°ïÅ|ªºµ{¦¡½X¡C

±µ¤U¨Óªº«ü¥O¬O¡usub rsp,30h¡v¡A¬°¦ó­n°õ¦æ¥¦©O¡H­ì¦]¬O¦b Input ¤º¡A·|©I¥s WriteConsoleA¡BReadConsoleA¡BStrToIntA¡A¨ä¤¤¥H WriteConsoleA ©Ò»Ýªº¤­­Ó°Ñ¼Æ³Ì¦h¡A©Ò¥H±o¦b°ïÅ|¤W¹w¯d¤­­Ó°Ñ¼ÆªºªÅ¶¡¡C¦ý¬O 5¡Ñ8¡×40¡×28h¡A¨º¬°¤°»ò¬O¨Ï RSP ´î¥h 30h¡A¦Ó¤£¬O´î¥h 28h ©O¡H³o­ì¦]²o¯A¨ì¦b°õ¦æ CALL «ü¥O®É¡A¤£¶È­n¹w¯d°Ñ¼ÆªÅ¶¡¡AÁÙ­n¨Ï RSP ¯à¹ï»ô¤@¸`ªº¦ì§}¡C­È±oª`·Nªº¬O¡A³o¨à¥u»Ý¦Ò¼{°Ñ¼Æ³Ì¦hªº§Y¥i¡A¦]¬°°Ñ¼Æ¸û¤Öªº¤@©w¥i¥H®e¯Ç¶i°Ñ¼Æ¸û¦hªº¡C

·í main °õ¦æ CALL «ü¥O©I¥s Input °Æµ{¦¡®É¡ARSP ¥²¶·«ü¦V¹ï»ô¤@¸`ªº¦ì§}¡A¨ä­Ó¦ì¼Æ¬O¹s¡C¶i¤J Input °Æµ{¦¡«á¡ACALL ·|§âªð¦^¦ì§}±À¤J°ïÅ|¡AInput ±µ¤U¨Ó·|§â RBP ±À¤J°ïÅ|«O¦s°_¨Ó¡A¨ì¦¹ RSP ªº­Ó¦ì¼Æ¤´¬O¹s¡C§Ú­Ì¥i¥H±o¨ì¤@­Ó¤p¤pªº·§©À¡A¨º´N¬O¨C¨âµ§¸ê®Æ±À¤J°ïÅ|¡ARSP ±N·|´î 10h¡A¤´µM¹ï»ô¤@¸`ªº¦ì§}¡C±µ¤U¨Ó°Ï°ìÅܼƦû¤F°ïÅ|¤Tµ§¸ê®Æ¡A¦Ó Input ¤S±N¤T­Ó¼È¦s¾¹±À¤J°ïÅ|¡AÁ`¦@¤»µ§¸ê®Æ¡A¨ì¦¹ RSP ¤´¹ï»ô¤@¸`ªº¦ì§}¡C¦¹®É­Y´î¥h 28h ·|¨Ï±o RSP ¦b°õ¦æ CALL ®É¨S¦³¹ï»ô¤@¸`¦ì§}¡A¦]¦¹­n­×¥¿¬°´î¥h 30h¡A§Y«K¬O®ö¶O¤F¤K­Ó¦ì¤¸²Õªº°ïÅ|ªÅ¶¡¡C

³Ì«á¦AÅo¶Û¤@¤U¡A­n°h¥X°Æµ{¦¡®É¡A¥i°Ñ¦Ò¤W¹Ï¤»¡C¥ý¨Ï RSP ¥[¤W 30h¡]¦¹¨BÆJ¥²¶·¥Ñµ{¦¡³]­pªº¤H¼¶¼g¡^¡A¨Ï¨ä«ü¦V«O¦s¼È¦s¾¹ªº¦a¤è¡A¦A¤@¤@«ì´_¼È¦s¾¹­ì­È¡]¦¹¨BÆJ¥Ñ²Õ;¹¦Û°Ê²K¥[¡^¡C±µ¤U¨Óªº LEAVE «ü¥O¬O²Õ;¹¦Û°Ê²K¥[ªº¡A¥¦¥i¨Ï RSP ¤§­ÈÅܬ° RBP¡A§Y 1FFA50¡AµM«á¥Ñ°ïÅ|«ì´_­ì¨Óªº RBP¡C³Ì«á°õ¦æ RET ªð¦^ main¡C

¦b¦¹°µ¤@­Ó¤p¤pªºµ²½×¡A¶i¤J°Æµ{¦¡«á¡A°ïÅ|®Øùتº¤º®e¡A¦ì§}¥Ñ°ª¦Ü§C¨Ì§Ç¬O¡G①ªð¦^¦ì§}¡]¤K­Ó¦ì¤¸²Õ¡^¡B②­ì RBP¡]¤K­Ó¦ì¤¸²Õ¡^¡B③°Ï°ìÅܼơ]¨Ì»Ý¨D¨M©w¡^¡B④«O¦sªº¼È¦s¾¹¡]¨Ì»Ý¨D¨M©w¡^¡B⑤¶i¤J°Æµ{¦¡«á¦A©I¥s°Æµ{¦¡¹w¯dªº°Ñ¼Æ¡]¥Ñ³Ì¦hªº°Ñ¼Æ»P¬O§_¹ï»ô¤@¸`ªº¦ì§}¨M©w¡^¡C


«á°O

³o¤@³¹¥Î¯Â¤â¤u¤è¦¡¥´³y GCD.EXE¡A¥Øªº¥u¯Âºé¬O¬°¤F»¡©ú°ïÅ|®Ø¤º®e¡A¦Ó¤£§Æ±æ¦]¬°¥]§tÀɪº¤Þ¤J¦Ó²K¥[³\¦h©_©_©Ç©Çªº¸Ë¹¢¡C©¹«á¦A¤]¤£·|¥Î³oºØ¤è¦¡¡A¦Ó¬Oª½±µ¯¸¦b¥¨¤HªºªÓ»H¤W¡A¨Ï¥Î MASM64 SDK¡AÅý³]­pÀ³¥Îµ{¦¡Åܱo²«K¤@¨Ç¡C