|  | extern _GetStdHandle@4 | 
        
          |  | extern _WriteConsoleA@20 | 
        
          |  | extern _ExitProcess@4 | 
        
          |  | extern _VirtualAlloc@16 | 
        
          |  |  | 
        
          |  | section .bss | 
        
          |  | numCharsWritten:        resb 1 | 
        
          |  |  | 
        
          |  | section .text | 
        
          |  |  | 
        
          |  | ; Allocates eax bytes of memory. Pointer to allocated memory returned in eax. | 
        
          |  | global __malloc | 
        
          |  | __malloc: | 
        
          |  | push eax                          ; back-up the size to be allocated | 
        
          |  | mov eax, [brk_region]             ; load the current brk region | 
        
          |  | test eax, eax                     ; if it's not been initialized yet, then | 
        
          |  | je  initialize_brk                ; initialize it | 
        
          |  | brk_initialized:                      ; eax now contains the region | 
        
          |  | pop ebx                           ; pop size to be allocated to ebx | 
        
          |  | push eax                          ; back it up | 
        
          |  | add eax, ebx                      ; adjust the pointer | 
        
          |  | mov [brk_region], eax             ; store the adjusted pointer | 
        
          |  | mov eax, [brk_region_size]        ; get the remaining region size | 
        
          |  | cmp eax, ebx                      ; if it less than the size we want to allocate | 
        
          |  | jb __exception                    ; goto exception | 
        
          |  | sub eax, ebx                      ; otherwise, update the remaining size | 
        
          |  | mov [brk_region_size], eax        ; store it | 
        
          |  | pop eax                           ; return the backed-up pointer to the region | 
        
          |  | ret | 
        
          |  |  | 
        
          |  | ; Initialize the brk by allocating a chunk of memory | 
        
          |  | initialize_brk: | 
        
          |  | push 0x04                         ; flag = PAGE_READWRITE | 
        
          |  | push 0x3000                       ; fAllocationType = MEM_COMMIT | MEM_RESERVE | 
        
          |  | mov eax, [brk_region_size]        ; get the size of the region (predefined) | 
        
          |  | push eax | 
        
          |  | push 0                            ; lpAddress = 0 | 
        
          |  | mov eax, 197 | 
        
          |  | call _VirtualAlloc@16             ; call VirtualAlloc with brk_region_size to allocate | 
        
          |  | test eax, eax                     ; if it fails then | 
        
          |  | je __exception                    ; goto exception | 
        
          |  | mov [brk_region], eax             ; set the pointer | 
        
          |  | jmp brk_initialized | 
        
          |  |  | 
        
          |  |  | 
        
          |  | ; Debugging exit: ends the process, returning the value of | 
        
          |  | ; eax as the exit code. | 
        
          |  | global __debexit | 
        
          |  | __debexit: | 
        
          |  | push    eax         ; Arg1: push exit code | 
        
          |  | call    _ExitProcess@4 | 
        
          |  |  | 
        
          |  | ; Exceptional exit: ends the process with exit code 13. | 
        
          |  | ; Call this in cases where the Joos code would throw an exception. | 
        
          |  | global __exception | 
        
          |  | __exception: | 
        
          |  | push    dword 13 | 
        
          |  | call    _ExitProcess@4 | 
        
          |  |  | 
        
          |  | ; Implementation of java.io.OutputStream.nativeWrite method. | 
        
          |  | ; Outputs the low-order byte of eax to standard output. | 
        
          |  | global NATIVEjava.io.OutputStream.nativeWrite | 
        
          |  | NATIVEjava.io.OutputStream.nativeWrite: | 
        
          |  | ; get std handle | 
        
          |  | mov     [char],     al ; save the low order byte in memory | 
        
          |  | push    dword -11 | 
        
          |  | call    _GetStdHandle@4 | 
        
          |  | push    dword 0         ; Arg5: Unused so just use zero | 
        
          |  | push    numCharsWritten ; Arg4: push pointer to numCharsWritten | 
        
          |  | push    dword 1         ; Arg3: push length of output string | 
        
          |  | push    char            ; Arg2: push pointer to output string | 
        
          |  | push    eax             ; Arg1: push handle returned from _GetStdHandle | 
        
          |  | call    _WriteConsoleA@20 | 
        
          |  | mov eax, 0              ; return 0 | 
        
          |  | ret | 
        
          |  |  | 
        
          |  | section .data | 
        
          |  | brk_region_size: | 
        
          |  | dd 4194304 | 
        
          |  | brk_region: | 
        
          |  | dd 0 | 
        
          |  | char: | 
        
          |  | dd 0 |