
; demo items:
; - custom proc before _start: versus after _start:
; - invoke versus stdcall versus push + call on standard procs versus custom procs

Format PE Console                        ; Win32 portable executable console format
Entry _start                             ; _start is the program's entry point

include 'Win32A.INC'

section '.data' data readable              ; definitions
  bolTru = 1                               ; constant for True
  bolFls = 0                               ; constant for False
  chrTrm = 0                               ; string-terminating character
  EOL    equ 13, 10                        ; Cr+Lf
  strTru db 'BoolPrint.True' , EOL, chrTrm ; message  for True  - EOL yes
  strFls db 'BoolPrint.False', EOL, chrTrm ; message  for False - EOL yes
  strMsg db 'I am Demo1.ASM '     , chrTrm ; message  bgn all   - EOL non
  strBgn db 'Bgn'            , EOL, chrTrm ; message  end one   - EOL yes
  strEnd db 'End'            , EOL, chrTrm ; message  end two   - EOL yes

section '.code' code readable executable ; code

;_start: ; uncomment this and comment line 38 to see the problem

  ; custom proc
  proc BoolPrint uses ebx, prmBol        ; input: 1/True or 0/False in eax; output: emit our 'True' or 'False' message
    cmp    [prmBol], 1  ; see if caller's variable is 1/True
    jne    BoolPrintNEq ; if No then skip to label for Not-Equal
    mov    ebx, strTru  ; point to string for True
    jmp    BoolPrintEmt ;   and      skip to label for Emit
  BoolPrintNEq:
    mov    ebx, strFls  ; point to string for False
  BoolPrintEmt:
    invoke printf, ebx  ; emit whichever string we just pointed to
    ret                 ; pass control back to caller
  endp                  ; BoolPrint

 _start: ; comment this and uncomment line 23 to see the problem

; ***** MAIN Bgn ***** ==========================================================================================
  invoke  printf     ,       strMsg ; emit our ID message directly          one bgn - good; implicit push + call
  invoke  printf     ,       strBgn ; emit our ID message directly          one end - good; implicit push + call

  push    strMsg                    ; populate      parameter with argument one bgn - good
  call   [printf]                   ; call standard function                        - good; explicit version of invoke

  push    strBgn                    ; populate      parameter with argument one end - good
  call   [printf]                   ; call standard function                        - good; explicit version of invoke
; ---------------------------------------------------------------------------------------------------------------
  stdcall BoolPrint  ,       bolTru ; call custom   function  with argument one     - good; implicit push + call
  stdcall BoolPrint  ,       bolFls ; call custom   function  with argument two     - good; implicit push + call

  push                       bolTru ; populate      parameter with argument one     - good; explicit version of stdcall
  call    BoolPrint                 ; call custom   function                        - good; explicit version of stdcall

  push                       bolFls ; populate parameter      with argument two     - good; explicit version of stdcall
  call    BoolPrint                 ; call custom   function                        - good; explicit version of stdcall
; -- How to invoke a custom function? ----------------------------------------------------------------------------
 ;invoke  BoolPrint  ,       bolTru ; implicit call             [ProcNam]           - asm fail: processed: call[BoolPrint]   error: operand size not specified.
 ;invoke  BoolPrint  ,  byte bolTru ; |        |                 |                  - asm fail: processed: pushd byte bolTru error: invalid size of operand.
 ;invoke  BoolPrint  ,  word bolTru ; |        |                 |                  - asm fail: processed: pushd word bolTru error: invalid size of operand.
 ;invoke  BoolPrint  , dword bolTru ; |        |                 |                  - asm fail: processed: call[BoolPrint]   error: operand size not specified.
 ;call   [BoolPrint]                ; explicit version of invoke ProcNam            - asm fail: processed: call[BoolPrint]   error: operand size not specified.
; ---------------------------------------------------------------------------------------------------------------
  invoke  printf     ,       strMsg ; emit our ID message directly          two bgn - good
  invoke  printf     ,       strEnd ; emit our ID message directly          two end - good

  invoke  ExitProcess, 0            ; pass control back to caller
; ***** MAIN End ***** ==========================================================================================

section '.imports' import data readable  ; external links and imports
  library kernel     , 'kernel32.dll', \ ; link to DLLs. Library symbol must be 'kernel' not 'kernel32'; 32 gives undefined symbol 'ExitProcess'
          msvcrt     , 'msvcrt.dll'

  import  kernel     ,                 \ ; import from kernel32
          ExitProcess, 'ExitProcess'

  import  msvcrt     ,                 \ ; import from msvcrt
          printf     , 'printf'
