github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/src/runtime/sys_linux_amd64.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 // 6 // System calls and other sys.stuff for AMD64, Linux 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 #define SYS_read 0 14 #define SYS_write 1 15 #define SYS_open 2 16 #define SYS_close 3 17 #define SYS_mmap 9 18 #define SYS_munmap 11 19 #define SYS_brk 12 20 #define SYS_rt_sigaction 13 21 #define SYS_rt_sigprocmask 14 22 #define SYS_rt_sigreturn 15 23 #define SYS_access 21 24 #define SYS_sched_yield 24 25 #define SYS_mincore 27 26 #define SYS_madvise 28 27 #define SYS_setittimer 38 28 #define SYS_getpid 39 29 #define SYS_socket 41 30 #define SYS_connect 42 31 #define SYS_clone 56 32 #define SYS_exit 60 33 #define SYS_kill 62 34 #define SYS_fcntl 72 35 #define SYS_getrlimit 97 36 #define SYS_sigaltstack 131 37 #define SYS_arch_prctl 158 38 #define SYS_gettid 186 39 #define SYS_tkill 200 40 #define SYS_futex 202 41 #define SYS_sched_getaffinity 204 42 #define SYS_epoll_create 213 43 #define SYS_exit_group 231 44 #define SYS_epoll_wait 232 45 #define SYS_epoll_ctl 233 46 #define SYS_pselect6 270 47 #define SYS_epoll_create1 291 48 49 TEXT runtime·exit(SB),NOSPLIT,$0-4 50 MOVL code+0(FP), DI 51 MOVL $SYS_exit_group, AX 52 SYSCALL 53 RET 54 55 TEXT runtime·exit1(SB),NOSPLIT,$0-4 56 MOVL code+0(FP), DI 57 MOVL $SYS_exit, AX 58 SYSCALL 59 RET 60 61 TEXT runtime·open(SB),NOSPLIT,$0-20 62 MOVQ name+0(FP), DI 63 MOVL mode+8(FP), SI 64 MOVL perm+12(FP), DX 65 MOVL $SYS_open, AX 66 SYSCALL 67 CMPQ AX, $0xfffffffffffff001 68 JLS 2(PC) 69 MOVL $-1, AX 70 MOVL AX, ret+16(FP) 71 RET 72 73 TEXT runtime·closefd(SB),NOSPLIT,$0-12 74 MOVL fd+0(FP), DI 75 MOVL $SYS_close, AX 76 SYSCALL 77 CMPQ AX, $0xfffffffffffff001 78 JLS 2(PC) 79 MOVL $-1, AX 80 MOVL AX, ret+8(FP) 81 RET 82 83 TEXT runtime·write(SB),NOSPLIT,$0-28 84 MOVQ fd+0(FP), DI 85 MOVQ p+8(FP), SI 86 MOVL n+16(FP), DX 87 MOVL $SYS_write, AX 88 SYSCALL 89 CMPQ AX, $0xfffffffffffff001 90 JLS 2(PC) 91 MOVL $-1, AX 92 MOVL AX, ret+24(FP) 93 RET 94 95 TEXT runtime·read(SB),NOSPLIT,$0-28 96 MOVL fd+0(FP), DI 97 MOVQ p+8(FP), SI 98 MOVL n+16(FP), DX 99 MOVL $SYS_read, AX 100 SYSCALL 101 CMPQ AX, $0xfffffffffffff001 102 JLS 2(PC) 103 MOVL $-1, AX 104 MOVL AX, ret+24(FP) 105 RET 106 107 TEXT runtime·getrlimit(SB),NOSPLIT,$0-20 108 MOVL kind+0(FP), DI 109 MOVQ limit+8(FP), SI 110 MOVL $SYS_getrlimit, AX 111 SYSCALL 112 MOVL AX, ret+16(FP) 113 RET 114 115 TEXT runtime·usleep(SB),NOSPLIT,$16 116 MOVL $0, DX 117 MOVL usec+0(FP), AX 118 MOVL $1000000, CX 119 DIVL CX 120 MOVQ AX, 0(SP) 121 MOVL $1000, AX // usec to nsec 122 MULL DX 123 MOVQ AX, 8(SP) 124 125 // pselect6(0, 0, 0, 0, &ts, 0) 126 MOVL $0, DI 127 MOVL $0, SI 128 MOVL $0, DX 129 MOVL $0, R10 130 MOVQ SP, R8 131 MOVL $0, R9 132 MOVL $SYS_pselect6, AX 133 SYSCALL 134 RET 135 136 TEXT runtime·gettid(SB),NOSPLIT,$0-4 137 MOVL $SYS_gettid, AX 138 SYSCALL 139 MOVL AX, ret+0(FP) 140 RET 141 142 TEXT runtime·raise(SB),NOSPLIT,$0 143 MOVL $SYS_gettid, AX 144 SYSCALL 145 MOVL AX, DI // arg 1 tid 146 MOVL sig+0(FP), SI // arg 2 147 MOVL $SYS_tkill, AX 148 SYSCALL 149 RET 150 151 TEXT runtime·raiseproc(SB),NOSPLIT,$0 152 MOVL $SYS_getpid, AX 153 SYSCALL 154 MOVL AX, DI // arg 1 pid 155 MOVL sig+0(FP), SI // arg 2 156 MOVL $SYS_kill, AX 157 SYSCALL 158 RET 159 160 TEXT runtime·setitimer(SB),NOSPLIT,$0-24 161 MOVL mode+0(FP), DI 162 MOVQ new+8(FP), SI 163 MOVQ old+16(FP), DX 164 MOVL $SYS_setittimer, AX 165 SYSCALL 166 RET 167 168 TEXT runtime·mincore(SB),NOSPLIT,$0-28 169 MOVQ addr+0(FP), DI 170 MOVQ n+8(FP), SI 171 MOVQ dst+16(FP), DX 172 MOVL $SYS_mincore, AX 173 SYSCALL 174 MOVL AX, ret+24(FP) 175 RET 176 177 // func walltime() (sec int64, nsec int32) 178 TEXT runtime·walltime(SB),NOSPLIT,$16 179 // Be careful. We're calling a function with gcc calling convention here. 180 // We're guaranteed 128 bytes on entry, and we've taken 16, and the 181 // call uses another 8. 182 // That leaves 104 for the gettime code to use. Hope that's enough! 183 MOVQ runtime·__vdso_clock_gettime_sym(SB), AX 184 CMPQ AX, $0 185 JEQ fallback 186 MOVL $0, DI // CLOCK_REALTIME 187 LEAQ 0(SP), SI 188 CALL AX 189 MOVQ 0(SP), AX // sec 190 MOVQ 8(SP), DX // nsec 191 MOVQ AX, sec+0(FP) 192 MOVL DX, nsec+8(FP) 193 RET 194 fallback: 195 LEAQ 0(SP), DI 196 MOVQ $0, SI 197 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX 198 CALL AX 199 MOVQ 0(SP), AX // sec 200 MOVL 8(SP), DX // usec 201 IMULQ $1000, DX 202 MOVQ AX, sec+0(FP) 203 MOVL DX, nsec+8(FP) 204 RET 205 206 TEXT runtime·nanotime(SB),NOSPLIT,$16 207 // Duplicate time.now here to avoid using up precious stack space. 208 // See comment above in time.now. 209 MOVQ runtime·__vdso_clock_gettime_sym(SB), AX 210 CMPQ AX, $0 211 JEQ fallback 212 MOVL $1, DI // CLOCK_MONOTONIC 213 LEAQ 0(SP), SI 214 CALL AX 215 MOVQ 0(SP), AX // sec 216 MOVQ 8(SP), DX // nsec 217 // sec is in AX, nsec in DX 218 // return nsec in AX 219 IMULQ $1000000000, AX 220 ADDQ DX, AX 221 MOVQ AX, ret+0(FP) 222 RET 223 fallback: 224 LEAQ 0(SP), DI 225 MOVQ $0, SI 226 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX 227 CALL AX 228 MOVQ 0(SP), AX // sec 229 MOVL 8(SP), DX // usec 230 IMULQ $1000, DX 231 // sec is in AX, nsec in DX 232 // return nsec in AX 233 IMULQ $1000000000, AX 234 ADDQ DX, AX 235 MOVQ AX, ret+0(FP) 236 RET 237 238 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28 239 MOVL how+0(FP), DI 240 MOVQ new+8(FP), SI 241 MOVQ old+16(FP), DX 242 MOVL size+24(FP), R10 243 MOVL $SYS_rt_sigprocmask, AX 244 SYSCALL 245 CMPQ AX, $0xfffffffffffff001 246 JLS 2(PC) 247 MOVL $0xf1, 0xf1 // crash 248 RET 249 250 TEXT runtime·sysSigaction(SB),NOSPLIT,$0-36 251 MOVQ sig+0(FP), DI 252 MOVQ new+8(FP), SI 253 MOVQ old+16(FP), DX 254 MOVQ size+24(FP), R10 255 MOVL $SYS_rt_sigaction, AX 256 SYSCALL 257 MOVL AX, ret+32(FP) 258 RET 259 260 // Call the function stored in _cgo_sigaction using the GCC calling convention. 261 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16 262 MOVQ sig+0(FP), DI 263 MOVQ new+8(FP), SI 264 MOVQ old+16(FP), DX 265 MOVQ _cgo_sigaction(SB), AX 266 MOVQ SP, BX // callee-saved 267 ANDQ $~15, SP // alignment as per amd64 psABI 268 CALL AX 269 MOVQ BX, SP 270 MOVL AX, ret+24(FP) 271 RET 272 273 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 274 MOVQ fn+0(FP), AX 275 MOVL sig+8(FP), DI 276 MOVQ info+16(FP), SI 277 MOVQ ctx+24(FP), DX 278 PUSHQ BP 279 MOVQ SP, BP 280 ANDQ $~15, SP // alignment for x86_64 ABI 281 CALL AX 282 MOVQ BP, SP 283 POPQ BP 284 RET 285 286 TEXT runtime·sigtramp(SB),NOSPLIT,$72 287 // Save callee-saved C registers, since the caller may be a C signal handler. 288 MOVQ BX, bx-8(SP) 289 MOVQ BP, bp-16(SP) // save in case GOEXPERIMENT=noframepointer is set 290 MOVQ R12, r12-24(SP) 291 MOVQ R13, r13-32(SP) 292 MOVQ R14, r14-40(SP) 293 MOVQ R15, r15-48(SP) 294 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't 295 // modify them. 296 297 MOVQ DX, ctx-56(SP) 298 MOVQ SI, info-64(SP) 299 MOVQ DI, signum-72(SP) 300 MOVQ $runtime·sigtrampgo(SB), AX 301 CALL AX 302 303 MOVQ r15-48(SP), R15 304 MOVQ r14-40(SP), R14 305 MOVQ r13-32(SP), R13 306 MOVQ r12-24(SP), R12 307 MOVQ bp-16(SP), BP 308 MOVQ bx-8(SP), BX 309 RET 310 311 // Used instead of sigtramp in programs that use cgo. 312 // Arguments from kernel are in DI, SI, DX. 313 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 314 // If no traceback function, do usual sigtramp. 315 MOVQ runtime·cgoTraceback(SB), AX 316 TESTQ AX, AX 317 JZ sigtramp 318 319 // If no traceback support function, which means that 320 // runtime/cgo was not linked in, do usual sigtramp. 321 MOVQ _cgo_callers(SB), AX 322 TESTQ AX, AX 323 JZ sigtramp 324 325 // Figure out if we are currently in a cgo call. 326 // If not, just do usual sigtramp. 327 get_tls(CX) 328 MOVQ g(CX),AX 329 TESTQ AX, AX 330 JZ sigtrampnog // g == nil 331 MOVQ g_m(AX), AX 332 TESTQ AX, AX 333 JZ sigtramp // g.m == nil 334 MOVL m_ncgo(AX), CX 335 TESTL CX, CX 336 JZ sigtramp // g.m.ncgo == 0 337 MOVQ m_curg(AX), CX 338 TESTQ CX, CX 339 JZ sigtramp // g.m.curg == nil 340 MOVQ g_syscallsp(CX), CX 341 TESTQ CX, CX 342 JZ sigtramp // g.m.curg.syscallsp == 0 343 MOVQ m_cgoCallers(AX), R8 344 TESTQ R8, R8 345 JZ sigtramp // g.m.cgoCallers == nil 346 MOVL m_cgoCallersUse(AX), CX 347 TESTL CX, CX 348 JNZ sigtramp // g.m.cgoCallersUse != 0 349 350 // Jump to a function in runtime/cgo. 351 // That function, written in C, will call the user's traceback 352 // function with proper unwind info, and will then call back here. 353 // The first three arguments, and the fifth, are already in registers. 354 // Set the two remaining arguments now. 355 MOVQ runtime·cgoTraceback(SB), CX 356 MOVQ $runtime·sigtramp(SB), R9 357 MOVQ _cgo_callers(SB), AX 358 JMP AX 359 360 sigtramp: 361 JMP runtime·sigtramp(SB) 362 363 sigtrampnog: 364 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 365 // stack trace. 366 CMPL DI, $27 // 27 == SIGPROF 367 JNZ sigtramp 368 369 // Lock sigprofCallersUse. 370 MOVL $0, AX 371 MOVL $1, CX 372 MOVQ $runtime·sigprofCallersUse(SB), R11 373 LOCK 374 CMPXCHGL CX, 0(R11) 375 JNZ sigtramp // Skip stack trace if already locked. 376 377 // Jump to the traceback function in runtime/cgo. 378 // It will call back to sigprofNonGo, which will ignore the 379 // arguments passed in registers. 380 // First three arguments to traceback function are in registers already. 381 MOVQ runtime·cgoTraceback(SB), CX 382 MOVQ $runtime·sigprofCallers(SB), R8 383 MOVQ $runtime·sigprofNonGo(SB), R9 384 MOVQ _cgo_callers(SB), AX 385 JMP AX 386 387 // For cgo unwinding to work, this function must look precisely like 388 // the one in glibc. The glibc source code is: 389 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sigaction.c 390 // The code that cares about the precise instructions used is: 391 // https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup 392 TEXT runtime·sigreturn(SB),NOSPLIT,$0 393 MOVQ $SYS_rt_sigreturn, AX 394 SYSCALL 395 INT $3 // not reached 396 397 TEXT runtime·sysMmap(SB),NOSPLIT,$0 398 MOVQ addr+0(FP), DI 399 MOVQ n+8(FP), SI 400 MOVL prot+16(FP), DX 401 MOVL flags+20(FP), R10 402 MOVL fd+24(FP), R8 403 MOVL off+28(FP), R9 404 405 MOVL $SYS_mmap, AX 406 SYSCALL 407 CMPQ AX, $0xfffffffffffff001 408 JLS 3(PC) 409 NOTQ AX 410 INCQ AX 411 MOVQ AX, ret+32(FP) 412 RET 413 414 // Call the function stored in _cgo_mmap using the GCC calling convention. 415 // This must be called on the system stack. 416 TEXT runtime·callCgoMmap(SB),NOSPLIT,$16 417 MOVQ addr+0(FP), DI 418 MOVQ n+8(FP), SI 419 MOVL prot+16(FP), DX 420 MOVL flags+20(FP), CX 421 MOVL fd+24(FP), R8 422 MOVL off+28(FP), R9 423 MOVQ _cgo_mmap(SB), AX 424 MOVQ SP, BX 425 ANDQ $~15, SP // alignment as per amd64 psABI 426 MOVQ BX, 0(SP) 427 CALL AX 428 MOVQ 0(SP), SP 429 MOVQ AX, ret+32(FP) 430 RET 431 432 TEXT runtime·sysMunmap(SB),NOSPLIT,$0 433 MOVQ addr+0(FP), DI 434 MOVQ n+8(FP), SI 435 MOVQ $SYS_munmap, AX 436 SYSCALL 437 CMPQ AX, $0xfffffffffffff001 438 JLS 2(PC) 439 MOVL $0xf1, 0xf1 // crash 440 RET 441 442 // Call the function stored in _cgo_munmap using the GCC calling convention. 443 // This must be called on the system stack. 444 TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16 445 MOVQ addr+0(FP), DI 446 MOVQ n+8(FP), SI 447 MOVQ _cgo_munmap(SB), AX 448 MOVQ SP, BX 449 ANDQ $~15, SP // alignment as per amd64 psABI 450 MOVQ BX, 0(SP) 451 CALL AX 452 MOVQ 0(SP), SP 453 RET 454 455 TEXT runtime·madvise(SB),NOSPLIT,$0 456 MOVQ addr+0(FP), DI 457 MOVQ n+8(FP), SI 458 MOVL flags+16(FP), DX 459 MOVQ $SYS_madvise, AX 460 SYSCALL 461 // ignore failure - maybe pages are locked 462 RET 463 464 // int64 futex(int32 *uaddr, int32 op, int32 val, 465 // struct timespec *timeout, int32 *uaddr2, int32 val2); 466 TEXT runtime·futex(SB),NOSPLIT,$0 467 MOVQ addr+0(FP), DI 468 MOVL op+8(FP), SI 469 MOVL val+12(FP), DX 470 MOVQ ts+16(FP), R10 471 MOVQ addr2+24(FP), R8 472 MOVL val3+32(FP), R9 473 MOVL $SYS_futex, AX 474 SYSCALL 475 MOVL AX, ret+40(FP) 476 RET 477 478 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 479 TEXT runtime·clone(SB),NOSPLIT,$0 480 MOVL flags+0(FP), DI 481 MOVQ stk+8(FP), SI 482 MOVQ $0, DX 483 MOVQ $0, R10 484 485 // Copy mp, gp, fn off parent stack for use by child. 486 // Careful: Linux system call clobbers CX and R11. 487 MOVQ mp+16(FP), R8 488 MOVQ gp+24(FP), R9 489 MOVQ fn+32(FP), R12 490 491 MOVL $SYS_clone, AX 492 SYSCALL 493 494 // In parent, return. 495 CMPQ AX, $0 496 JEQ 3(PC) 497 MOVL AX, ret+40(FP) 498 RET 499 500 // In child, on new stack. 501 MOVQ SI, SP 502 503 // If g or m are nil, skip Go-related setup. 504 CMPQ R8, $0 // m 505 JEQ nog 506 CMPQ R9, $0 // g 507 JEQ nog 508 509 // Initialize m->procid to Linux tid 510 MOVL $SYS_gettid, AX 511 SYSCALL 512 MOVQ AX, m_procid(R8) 513 514 // Set FS to point at m->tls. 515 LEAQ m_tls(R8), DI 516 CALL runtime·settls(SB) 517 518 // In child, set up new stack 519 get_tls(CX) 520 MOVQ R8, g_m(R9) 521 MOVQ R9, g(CX) 522 CALL runtime·stackcheck(SB) 523 524 nog: 525 // Call fn 526 CALL R12 527 528 // It shouldn't return. If it does, exit that thread. 529 MOVL $111, DI 530 MOVL $SYS_exit, AX 531 SYSCALL 532 JMP -3(PC) // keep exiting 533 534 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 535 MOVQ new+0(FP), DI 536 MOVQ old+8(FP), SI 537 MOVQ $SYS_sigaltstack, AX 538 SYSCALL 539 CMPQ AX, $0xfffffffffffff001 540 JLS 2(PC) 541 MOVL $0xf1, 0xf1 // crash 542 RET 543 544 // set tls base to DI 545 TEXT runtime·settls(SB),NOSPLIT,$32 546 #ifdef GOOS_android 547 // Same as in sys_darwin_386.s:/ugliness, different constant. 548 // DI currently holds m->tls, which must be fs:0x1d0. 549 // See cgo/gcc_android_amd64.c for the derivation of the constant. 550 SUBQ $0x1d0, DI // In android, the tls base 551 #else 552 ADDQ $8, DI // ELF wants to use -8(FS) 553 #endif 554 MOVQ DI, SI 555 MOVQ $0x1002, DI // ARCH_SET_FS 556 MOVQ $SYS_arch_prctl, AX 557 SYSCALL 558 CMPQ AX, $0xfffffffffffff001 559 JLS 2(PC) 560 MOVL $0xf1, 0xf1 // crash 561 RET 562 563 TEXT runtime·osyield(SB),NOSPLIT,$0 564 MOVL $SYS_sched_yield, AX 565 SYSCALL 566 RET 567 568 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 569 MOVQ pid+0(FP), DI 570 MOVQ len+8(FP), SI 571 MOVQ buf+16(FP), DX 572 MOVL $SYS_sched_getaffinity, AX 573 SYSCALL 574 MOVL AX, ret+24(FP) 575 RET 576 577 // int32 runtime·epollcreate(int32 size); 578 TEXT runtime·epollcreate(SB),NOSPLIT,$0 579 MOVL size+0(FP), DI 580 MOVL $SYS_epoll_create, AX 581 SYSCALL 582 MOVL AX, ret+8(FP) 583 RET 584 585 // int32 runtime·epollcreate1(int32 flags); 586 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 587 MOVL flags+0(FP), DI 588 MOVL $SYS_epoll_create1, AX 589 SYSCALL 590 MOVL AX, ret+8(FP) 591 RET 592 593 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 594 TEXT runtime·epollctl(SB),NOSPLIT,$0 595 MOVL epfd+0(FP), DI 596 MOVL op+4(FP), SI 597 MOVL fd+8(FP), DX 598 MOVQ ev+16(FP), R10 599 MOVL $SYS_epoll_ctl, AX 600 SYSCALL 601 MOVL AX, ret+24(FP) 602 RET 603 604 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 605 TEXT runtime·epollwait(SB),NOSPLIT,$0 606 MOVL epfd+0(FP), DI 607 MOVQ ev+8(FP), SI 608 MOVL nev+16(FP), DX 609 MOVL timeout+20(FP), R10 610 MOVL $SYS_epoll_wait, AX 611 SYSCALL 612 MOVL AX, ret+24(FP) 613 RET 614 615 // void runtime·closeonexec(int32 fd); 616 TEXT runtime·closeonexec(SB),NOSPLIT,$0 617 MOVL fd+0(FP), DI // fd 618 MOVQ $2, SI // F_SETFD 619 MOVQ $1, DX // FD_CLOEXEC 620 MOVL $SYS_fcntl, AX 621 SYSCALL 622 RET 623 624 625 // int access(const char *name, int mode) 626 TEXT runtime·access(SB),NOSPLIT,$0 627 MOVQ name+0(FP), DI 628 MOVL mode+8(FP), SI 629 MOVL $SYS_access, AX 630 SYSCALL 631 MOVL AX, ret+16(FP) 632 RET 633 634 // int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) 635 TEXT runtime·connect(SB),NOSPLIT,$0-28 636 MOVL fd+0(FP), DI 637 MOVQ addr+8(FP), SI 638 MOVL len+16(FP), DX 639 MOVL $SYS_connect, AX 640 SYSCALL 641 MOVL AX, ret+24(FP) 642 RET 643 644 // int socket(int domain, int type, int protocol) 645 TEXT runtime·socket(SB),NOSPLIT,$0-20 646 MOVL domain+0(FP), DI 647 MOVL typ+4(FP), SI 648 MOVL prot+8(FP), DX 649 MOVL $SYS_socket, AX 650 SYSCALL 651 MOVL AX, ret+16(FP) 652 RET 653 654 // func sbrk0() uintptr 655 TEXT runtime·sbrk0(SB),NOSPLIT,$0-8 656 // Implemented as brk(NULL). 657 MOVQ $0, DI 658 MOVL $SYS_brk, AX 659 SYSCALL 660 MOVQ AX, ret+0(FP) 661 RET