github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/runtime/sys_windows_386.s (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "zasm_GOOS_GOARCH.h" 6 7 // void runtime·asmstdcall(void *c); 8 TEXT runtime·asmstdcall(SB),7,$0 9 MOVL c+0(FP), BX 10 11 // SetLastError(0). 12 MOVL $0, 0x34(FS) 13 14 // Copy args to the stack. 15 MOVL SP, BP 16 MOVL wincall_n(BX), CX // words 17 MOVL CX, AX 18 SALL $2, AX 19 SUBL AX, SP // room for args 20 MOVL SP, DI 21 MOVL wincall_args(BX), SI 22 CLD 23 REP; MOVSL 24 25 // Call stdcall or cdecl function. 26 // DI SI BP BX are preserved, SP is not 27 CALL wincall_fn(BX) 28 MOVL BP, SP 29 30 // Return result. 31 MOVL c+0(FP), BX 32 MOVL AX, wincall_r1(BX) 33 MOVL DX, wincall_r2(BX) 34 35 // GetLastError(). 36 MOVL 0x34(FS), AX 37 MOVL AX, wincall_err(BX) 38 39 RET 40 41 TEXT runtime·badcallback(SB),7,$24 42 // stderr 43 MOVL $-12, 0(SP) 44 MOVL SP, BP 45 CALL *runtime·GetStdHandle(SB) 46 MOVL BP, SP 47 48 MOVL AX, 0(SP) // handle 49 MOVL $runtime·badcallbackmsg(SB), DX // pointer 50 MOVL DX, 4(SP) 51 MOVL runtime·badcallbacklen(SB), DX // count 52 MOVL DX, 8(SP) 53 LEAL 20(SP), DX // written count 54 MOVL $0, 0(DX) 55 MOVL DX, 12(SP) 56 MOVL $0, 16(SP) // overlapped 57 CALL *runtime·WriteFile(SB) 58 MOVL BP, SI 59 RET 60 61 TEXT runtime·badsignal(SB),7,$24 62 // stderr 63 MOVL $-12, 0(SP) 64 MOVL SP, BP 65 CALL *runtime·GetStdHandle(SB) 66 MOVL BP, SP 67 68 MOVL AX, 0(SP) // handle 69 MOVL $runtime·badsignalmsg(SB), DX // pointer 70 MOVL DX, 4(SP) 71 MOVL runtime·badsignallen(SB), DX // count 72 MOVL DX, 8(SP) 73 LEAL 20(SP), DX // written count 74 MOVL $0, 0(DX) 75 MOVL DX, 12(SP) 76 MOVL $0, 16(SP) // overlapped 77 CALL *runtime·WriteFile(SB) 78 MOVL BP, SI 79 RET 80 81 // faster get/set last error 82 TEXT runtime·getlasterror(SB),7,$0 83 MOVL 0x34(FS), AX 84 RET 85 86 TEXT runtime·setlasterror(SB),7,$0 87 MOVL err+0(FP), AX 88 MOVL AX, 0x34(FS) 89 RET 90 91 TEXT runtime·sigtramp(SB),7,$28 92 // unwinding? 93 MOVL info+0(FP), CX 94 TESTL $6, 4(CX) // exception flags 95 MOVL $1, AX 96 JNZ sigdone 97 98 // copy arguments for call to sighandler 99 MOVL CX, 0(SP) 100 MOVL context+8(FP), CX 101 MOVL CX, 4(SP) 102 103 get_tls(CX) 104 105 // check that m exists 106 MOVL m(CX), AX 107 CMPL AX, $0 108 JNE 2(PC) 109 CALL runtime·badsignal(SB) 110 111 MOVL g(CX), CX 112 MOVL CX, 8(SP) 113 114 MOVL BX, 12(SP) 115 MOVL BP, 16(SP) 116 MOVL SI, 20(SP) 117 MOVL DI, 24(SP) 118 119 CALL runtime·sighandler(SB) 120 // AX is set to report result back to Windows 121 122 MOVL 24(SP), DI 123 MOVL 20(SP), SI 124 MOVL 16(SP), BP 125 MOVL 12(SP), BX 126 sigdone: 127 RET 128 129 TEXT runtime·ctrlhandler(SB),7,$0 130 PUSHL $runtime·ctrlhandler1(SB) 131 CALL runtime·externalthreadhandler(SB) 132 MOVL 4(SP), CX 133 ADDL $12, SP 134 JMP CX 135 136 TEXT runtime·profileloop(SB),7,$0 137 PUSHL $runtime·profileloop1(SB) 138 CALL runtime·externalthreadhandler(SB) 139 MOVL 4(SP), CX 140 ADDL $12, SP 141 JMP CX 142 143 TEXT runtime·externalthreadhandler(SB),7,$0 144 PUSHL BP 145 MOVL SP, BP 146 PUSHL BX 147 PUSHL SI 148 PUSHL DI 149 PUSHL 0x14(FS) 150 MOVL SP, DX 151 152 // setup dummy m, g 153 SUBL $m_end, SP // space for M 154 MOVL SP, 0(SP) 155 MOVL $m_end, 4(SP) 156 CALL runtime·memclr(SB) // smashes AX,BX,CX 157 158 LEAL m_tls(SP), CX 159 MOVL CX, 0x14(FS) 160 MOVL SP, m(CX) 161 MOVL SP, BX 162 SUBL $g_end, SP // space for G 163 MOVL SP, g(CX) 164 MOVL SP, m_g0(BX) 165 166 MOVL SP, 0(SP) 167 MOVL $g_end, 4(SP) 168 CALL runtime·memclr(SB) // smashes AX,BX,CX 169 LEAL -4096(SP), CX 170 MOVL CX, g_stackguard(SP) 171 MOVL DX, g_stackbase(SP) 172 173 PUSHL 16(BP) // arg for handler 174 CALL 8(BP) 175 POPL CX 176 177 get_tls(CX) 178 MOVL g(CX), CX 179 MOVL g_stackbase(CX), SP 180 POPL 0x14(FS) 181 POPL DI 182 POPL SI 183 POPL BX 184 POPL BP 185 RET 186 187 // Called from dynamic function created by ../thread.c compilecallback, 188 // running on Windows stack (not Go stack). 189 // BX, BP, SI, DI registers and DF flag are preserved 190 // as required by windows callback convention. 191 // AX = address of go func we need to call 192 // DX = total size of arguments 193 // 194 TEXT runtime·callbackasm+0(SB),7,$0 195 // preserve whatever's at the memory location that 196 // the callback will use to store the return value 197 LEAL 8(SP), CX 198 PUSHL 0(CX)(DX*1) 199 ADDL $4, DX // extend argsize by size of return value 200 201 // save registers as required for windows callback 202 PUSHL DI 203 PUSHL SI 204 PUSHL BP 205 PUSHL BX 206 207 // set up SEH frame again 208 PUSHL $runtime·sigtramp(SB) 209 PUSHL 0(FS) 210 MOVL SP, 0(FS) 211 212 // callback parameters 213 PUSHL DX 214 PUSHL CX 215 PUSHL AX 216 217 CLD 218 219 CALL runtime·cgocallback_gofunc(SB) 220 221 POPL AX 222 POPL CX 223 POPL DX 224 225 // pop SEH frame 226 POPL 0(FS) 227 POPL BX 228 229 // restore registers as required for windows callback 230 POPL BX 231 POPL BP 232 POPL SI 233 POPL DI 234 235 CLD 236 237 MOVL -4(CX)(DX*1), AX 238 POPL -4(CX)(DX*1) 239 RET 240 241 // void tstart(M *newm); 242 TEXT runtime·tstart(SB),7,$0 243 MOVL newm+4(SP), CX // m 244 MOVL m_g0(CX), DX // g 245 246 // Layout new m scheduler stack on os stack. 247 MOVL SP, AX 248 MOVL AX, g_stackbase(DX) 249 SUBL $(64*1024), AX // stack size 250 MOVL AX, g_stackguard(DX) 251 252 // Set up tls. 253 LEAL m_tls(CX), SI 254 MOVL SI, 0x14(FS) 255 MOVL CX, m(SI) 256 MOVL DX, g(SI) 257 258 // Someday the convention will be D is always cleared. 259 CLD 260 261 CALL runtime·stackcheck(SB) // clobbers AX,CX 262 CALL runtime·mstart(SB) 263 264 RET 265 266 // uint32 tstart_stdcall(M *newm); 267 TEXT runtime·tstart_stdcall(SB),7,$0 268 MOVL newm+4(SP), BX 269 270 PUSHL BX 271 CALL runtime·tstart(SB) 272 POPL BX 273 274 // Adjust stack for stdcall to return properly. 275 MOVL (SP), AX // save return address 276 ADDL $4, SP // remove single parameter 277 MOVL AX, (SP) // restore return address 278 279 XORL AX, AX // return 0 == success 280 281 RET 282 283 // setldt(int entry, int address, int limit) 284 TEXT runtime·setldt(SB),7,$0 285 MOVL address+4(FP), CX 286 MOVL CX, 0x14(FS) 287 RET 288 289 // void install_exception_handler() 290 TEXT runtime·install_exception_handler(SB),7,$0 291 get_tls(CX) 292 MOVL m(CX), CX // m 293 294 // Set up SEH frame 295 MOVL m_seh(CX), DX 296 MOVL $runtime·sigtramp(SB), AX 297 MOVL AX, seh_handler(DX) 298 MOVL 0(FS), AX 299 MOVL AX, seh_prev(DX) 300 301 // Install it 302 MOVL DX, 0(FS) 303 304 RET 305 306 // void remove_exception_handler() 307 TEXT runtime·remove_exception_handler(SB),7,$0 308 get_tls(CX) 309 MOVL m(CX), CX // m 310 311 // Remove SEH frame 312 MOVL m_seh(CX), DX 313 MOVL seh_prev(DX), AX 314 MOVL AX, 0(FS) 315 316 RET 317 318 TEXT runtime·osyield(SB),7,$20 319 // Tried NtYieldExecution but it doesn't yield hard enough. 320 // NtWaitForSingleObject being used here as Sleep(0). 321 MOVL runtime·NtWaitForSingleObject(SB), AX 322 MOVL $-1, hi-4(SP) 323 MOVL $-1, lo-8(SP) 324 LEAL lo-8(SP), BX 325 MOVL BX, ptime-12(SP) 326 MOVL $0, alertable-16(SP) 327 MOVL $-1, handle-20(SP) 328 MOVL SP, BP 329 CALL checkstack4<>(SB) 330 CALL AX 331 MOVL BP, SP 332 RET 333 334 TEXT runtime·usleep(SB),7,$20 335 MOVL runtime·NtWaitForSingleObject(SB), AX 336 // Have 1us units; need negative 100ns units. 337 // Assume multiply by 10 will not overflow 32-bit word. 338 MOVL usec+0(FP), BX 339 IMULL $10, BX 340 NEGL BX 341 MOVL $-1, hi-4(SP) 342 MOVL BX, lo-8(SP) 343 LEAL lo-8(SP), BX 344 MOVL BX, ptime-12(SP) 345 MOVL $0, alertable-16(SP) 346 MOVL $-1, handle-20(SP) 347 MOVL SP, BP 348 CALL checkstack4<>(SB) 349 CALL AX 350 MOVL BP, SP 351 RET 352 353 // This function requires 4 bytes of stack, 354 // to simulate what calling NtWaitForSingleObject will use. 355 // (It is just a CALL to the system call dispatch.) 356 // If the linker okays the call to checkstack4 (a NOSPLIT function) 357 // then the call to NtWaitForSingleObject is okay too. 358 TEXT checkstack4<>(SB),7,$4 359 RET