title: What is wrong with io.h, getting errors?
body: <p>This is straight out of my textbook, not sure what caused this. It worked before...</p>
  
  <p>Book code I am using:</p>
  
  <pre><code>; Input x and y, call procedure to evaluate 3*x+7*y, display result
  ; Author:  R. Detmer
  ; Date:    6/2013
  .586
  .MODEL FLAT
  INCLUDE io.h
  .STACK 4096
  
  .DATA
  number1 DWORD   ?
  number2 DWORD   ?
  prompt1 BYTE    "Enter first number x", 0
  prompt2 BYTE    "Enter second number y", 0
  string  BYTE    20 DUP (?)
  resultLbl BYTE  "3*x+7*y", 0
  result  BYTE    11 DUP (?), 0
  
  .CODE
  _MainProc PROC
          input   prompt1, string, 20      ; read ASCII characters
          atod    string          ; convert to integer
          mov     number1, eax    ; store in memory
  
          input   prompt2, string, 20      ; repeat for second number
          atod    string
          mov     number2, eax
  
          push    number2         ; 2nd parameter
          push    number1         ; 1st parameter
          call    fctn1           ; fctn1(number1, number2)
          add     esp, 8          ; remove parameters from stack
  
          dtoa    result, eax     ; convert to ASCII characters
          output  resultLbl, result  ; output label and result
  
          mov     eax, 0  ; exit with return code 0
          ret
  _MainProc ENDP
  
  ; int fctn1(int x, int y)
  ; returns 3*x+7*y
  fctn1   PROC
          push    ebp             ; save base pointer
          mov     ebp, esp        ; establish stack frame
          push    ebx             ; save EBX
  
          mov     eax, [ebp+8]    ; x
          imul    eax, 3          ; 3*x
          mov     ebx, [ebp+12]   ; y
          imul    ebx, 7          ; 7*y
          add     eax, ebx        ; 3*x + 7*y
  
          pop     ebx             ; restore EBX
          pop     ebp             ; restore EBP
          ret                     ; return      
  fctn1   ENDP
  
  END
  </code></pre>
  
  <p>Errors:</p>
  
  <pre><code>Error   101 error A1012: error count exceeds 100; stopping assembly C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\io.h 102 1   console32
  Error   3   error A2008: syntax error : *   C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\io.h 3   1   console32
  Error   13  error A2044: invalid character in file  C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\io.h 14  1   console32
  Error   102 error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\Source.obj" /W3 /errorReport:prompt /Fl /TaSource.asm" exited with code 1.  C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\BuildCustomizations\masm.targets 49  5   console32
  </code></pre>
  
  <p>I removed duplicate erros to make it look cleaner/neater.
  I attempted to edit the header file to remove the comments, but I don't have rights to write to it. I also don't think it's necessary to edit this file, because it used to work. And I am using the books files and code.</p>
  
  <p>I tried this on my laptop also and it gives me the same errors. I am using visual studio 2012 on both machines.</p>
  
  <p>If you need more info let me know.</p>
  
  <p>Using io.h in a windows32 assembly program.
  Open VS --> New Project --> c/c++ --> Windows32 (NOT console32) --> blank project.
  In solution explorer right click sources folder --> add new item --> c++ file (.cpp) and give it a name of your choice with the extension .asm instead of .cpp.
  code:</p>
  
  <pre><code>.586
  .MODEL FLAT
  INCLUDE io.h            ; header file for input/output
  
  .STACK 4096
  
  .DATA
  firstInput DWORD    ?                       ; Reserve DWORD sized named memory for 1st input
  secondInput DWORD   ?                       ; Reserve DWORD sized named memory for 2nd input
  prompt1 BYTE    "Enter first number",  0    ; Prompt user for the first input
  prompt2 BYTE    "Enter second number", 0    ; Prompt user for the second input
  inputString  BYTE    11 DUP (?)             ; Reserve memory for to store inputs 
                                              ; as integer max integer is 10 digits big
  resultLbl BYTE  "GCD", 0                    ; label for dialogBox
  
  resultLb2 BYTE  "The GCD is:"               ; String to be diplayed in the dialogBox
  gcdResult BYTE  10 DUP (?), 0               ; to display " The GCD is:" and then gcdInput
  
  .CODE
  _MainProc PROC
      ;************************ GET FIRST INPUT ************************
          input   prompt1, inputString, 11    ; read ASCII characters
                                              ; Max length for integer is 10 digits
          atod    inputString                 ; convert to integer
          mov     firstInput, eax             ; store in memory
      ;************************ GET SECOND INPUT ***********************
                                              ; repeat for second number
          input   prompt2, inputString, 11    ; read ASCII characters
          atod    inputString                 ; convert to integer
          mov     secondInput, eax            ; store in memory
  
          ;******************** THEORY IN PSUDOCODE  *******************
          ; gcdInput is firstInput
          ; remainder is secondInput
          ; loop:
          ; dividend is gcdInput
          ; gcdInput is remainder
          ; 
          ; firstInput and secondInput are reserved memory
          ; dividend is stored in  EAX ---&gt; numerator
          ; gcdInput is stored in  EBX ---&gt; denominator       
          ; remainder is stored in EDX ---&gt; remainder
          ; quotient  is stored in EAX ---&gt; quotient      
          ; EAX/EBX ---&gt; quotient will be stored in EAX
          ;             remainder will be stored in EDX
          ;             based on CPU logic
      ;************************ FIND GCD OF 2 NUMBERS ******************
          mov     EBX, firstInput     ; Copy named memory to EBX
          mov     EDX, secondInput    ; Copy named memory to EDX 
  
  findTheGCD:                 ; DO
          mov     EAX, EBX    ;   Copy gcdInput to EAX. Second pass and so on will
                              ;   copy the denominator to the numerator
          mov     EBX, EDX    ;   Copy remainder to EBX Second pass and so on will
                              ;   copy the remainder to the denominator
          mov     EDX, 0      ;   cdq is for signed, so instead of cdq move 0 to EDX.
                              ;   cdq expands EAX to EDX:EAX filling EDX with the sign bit
                              ;   Since our numbers are positive our sign bit is 0
                              ;   So filling EDX with 0's is the same as cdq would do.
                              ;   We are not using cdq and we are using div because we 
                              ;   are working with unsigned integers. 
                              ;   Clear out previous remainder
          div     EBX         ;   Divide EDX:EAX/EBX (dividend/gcdInput)
                              ;   second pass and so on will divide
                              ;   the denominator by the numerator repeatedly
                              ;   until the remainder is 0
                              ;   Quotient does not matter in this situation
                              ;   After the division process EAX will contain the quotient
                              ;   And EDX will contain the remainder, thus the 0's we filled
                              ;   it with will be overwritten with the remainder
          cmp     EDX, 0      ;   Compare EDX (remainder) to 0
                              ;   Since the 0's were overwritten with the remainder after the division
                              ;   the compare will see the new remainder NOT the 0's that was in it before!!
          jne     findTheGCD  ; UNTIL ( remainder == 0 )
  
      ;************************ PRINT THE GCD TO SCREEN ******************     
          dtoa    gcdResult, EBX        ; convert to ASCII characters
          output  resultLbl, resultLb2  ; output label and gcd string
  
          mov     eax, 0  ; exit with return code 0
          ret
  _MainProc ENDP
  END 
  </code></pre>
  
  <p><strong>Using io.h in a windows32 assembly program.</strong>
  Open VS --> New Project --> c/c++ --> Windows32 (NOT console32) --> blank project.
  In solution explorer right click sources folder --> add new item --> c++ file (.cpp) and give it a name of your choice with the extension .asm instead of .cpp.
  code:</p>
  
  <pre><code>.586
  .MODEL FLAT
  INCLUDE io.h            ; header file for input/output
  
  .STACK 4096
  
  .DATA
  firstInput DWORD    ?                       ; Reserve DWORD sized named memory for 1st input
  secondInput DWORD   ?                       ; Reserve DWORD sized named memory for 2nd input
  prompt1 BYTE    "Enter first number",  0    ; Prompt user for the first input
  prompt2 BYTE    "Enter second number", 0    ; Prompt user for the second input
  inputString  BYTE    11 DUP (?)             ; Reserve memory for to store inputs 
                                              ; as integer max integer is 10 digits big
  resultLbl BYTE  "GCD", 0                    ; label for dialogBox
  
  resultLb2 BYTE  "The GCD is:"               ; String to be diplayed in the dialogBox
  gcdResult BYTE  10 DUP (?), 0               ; to display " The GCD is:" and then gcdInput
  
  .CODE
  _MainProc PROC
      ;************************ GET FIRST INPUT ************************
          input   prompt1, inputString, 11    ; read ASCII characters
                                              ; Max length for integer is 10 digits
          atod    inputString                 ; convert to integer
          mov     firstInput, eax             ; store in memory
      ;************************ GET SECOND INPUT ***********************
                                              ; repeat for second number
          input   prompt2, inputString, 11    ; read ASCII characters
          atod    inputString                 ; convert to integer
          mov     secondInput, eax            ; store in memory
  
          ;******************** THEORY IN PSUDOCODE  *******************
          ; gcdInput is firstInput
          ; remainder is secondInput
          ; loop:
          ; dividend is gcdInput
          ; gcdInput is remainder
          ; 
          ; firstInput and secondInput are reserved memory
          ; dividend is stored in  EAX ---&gt; numerator
          ; gcdInput is stored in  EBX ---&gt; denominator       
          ; remainder is stored in EDX ---&gt; remainder
          ; quotient  is stored in EAX ---&gt; quotient      
          ; EAX/EBX ---&gt; quotient will be stored in EAX
          ;             remainder will be stored in EDX
          ;             based on CPU logic
      ;************************ FIND GCD OF 2 NUMBERS ******************
          mov     EBX, firstInput     ; Copy named memory to EBX
          mov     EDX, secondInput    ; Copy named memory to EDX 
  
  findTheGCD:                 ; DO
          mov     EAX, EBX    ;   Copy gcdInput to EAX. Second pass and so on will
                              ;   copy the denominator to the numerator
          mov     EBX, EDX    ;   Copy remainder to EBX Second pass and so on will
                              ;   copy the remainder to the denominator
          mov     EDX, 0      ;   cdq is for signed, so instead of cdq move 0 to EDX.
                              ;   cdq expands EAX to EDX:EAX filling EDX with the sign bit
                              ;   Since our numbers are positive our sign bit is 0
                              ;   So filling EDX with 0's is the same as cdq would do.
                              ;   We are not using cdq and we are using div because we 
                              ;   are working with unsigned integers. 
                              ;   Clear out previous remainder
          div     EBX         ;   Divide EDX:EAX/EBX (dividend/gcdInput)
                              ;   second pass and so on will divide
                              ;   the denominator by the numerator repeatedly
                              ;   until the remainder is 0
                              ;   Quotient does not matter in this situation
                              ;   After the division process EAX will contain the quotient
                              ;   And EDX will contain the remainder, thus the 0's we filled
                              ;   it with will be overwritten with the remainder
          cmp     EDX, 0      ;   Compare EDX (remainder) to 0
                              ;   Since the 0's were overwritten with the remainder after the division
                              ;   the compare will see the new remainder NOT the 0's that was in it before!!
          jne     findTheGCD  ; UNTIL ( remainder == 0 )
  
      ;************************ PRINT THE GCD TO SCREEN ******************     
          dtoa    gcdResult, EBX        ; convert to ASCII characters
          output  resultLbl, resultLb2  ; output label and gcd string
  
          mov     eax, 0  ; exit with return code 0
          ret
  _MainProc ENDP
  END 
  </code></pre>