Hello,
I'm learning Assembly and i'm using this code:
;*****************************************
;* Programa: CONDIC3.ASM *
;*****************************************
.MODEL small
.STACK 512d
.DATA
msg1 DB "Entre um valor numerico positivo(de 0 ate 9): ", $
msg2 DB "Valor impar", $
msg3 DB "Valor par", $
msg4 DB "Caractere invalido", $
.CODE
Lea DX, msg1
Call escreva
Mov AH, 01h
Int 021h
Cmp AL, 030h
Jge erro
Cmp AL,03Ah
Jge erro
Sub AL, 030h
And AL, 01h
Jpe par
Jpo impar
par:
Lea DX, msg3
Call escreva
Jmp saida
impar:
Lea DX,msg2
Call escreva
Jmp saida
erro:
Lea DX,msg4
Call escreva
Jmp saida
saida:
Int 020h
escreva PROC NEAR
Mov AH, 09h
Int 021h
Ret
escreva EndP
And here is the compiler log:
C:\masm32\bin\ML /c /coff /Cp /nologo /I"C:\masm32\include" "C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm"
Assembling: C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm
C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm(54) : error A2088: END directive required at end of file
C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm(9) : error A2071: initializer magnitude too large for specified size
C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm(10) : error A2071: initializer magnitude too large for specified size
C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm(11) : error A2071: initializer magnitude too large for specified size
C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm(12) : error A2071: initializer magnitude too large for specified size
C:\masm32\bin\Link @"C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\link.war"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 "/LIBPATH:\Masm32\Lib" "C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.obj" "/OUT:C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.exe"
LINK : fatal error LNK1181: cannot open input file "C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.obj"
Make finished. 6 error(s) occured.
What is wrong?
Thanks,
Nathan Paulino Campos
hi Nathan
1) the $ terminator should also be inside quotes (or define it as 24h or 36)
2) at the very end of the file, you need an END directive with the entry point
3) you need offsets - not lea's
4) you need to use a 16-bit linker instead of a 32-bit linker
5) this is 16-bit code and should post in the the 16-bit forum (bottom of forum list)
;*****************************************
;* Programa: CONDIC3.ASM *
;*****************************************
.MODEL small
.STACK 512d
.DATA
msg1 DB "Entre um valor numerico positivo(de 0 ate 9): ",24h
msg2 DB "Valor impar",24h
msg3 DB "Valor par",24h
msg4 DB "Caractere invalido",24h
.CODE
Entrar:
mov DX,offset msg1
Call escreva
Mov AH, 01h
Int 021h
Cmp AL, 030h
Jge erro
Cmp AL,03Ah
Jge erro
Sub AL, 030h
And AL, 01h
Jpe par
Jpo impar
par:
mov DX,offset msg3
Call escreva
Jmp saida
impar:
mov DX,offset msg2
Call escreva
Jmp saida
erro:
mov DX,offset msg4
Call escreva
Jmp saida
saida:
Int 020h
escreva PROC NEAR
Mov AH, 09h
Int 021h
Ret
escreva EndP
END Entrar
Nathan,
To enlarge on the information that Dave provided, the first problem is the 5 syntax errors that ML is reporting. If these problems are corrected then the code will assemble without error. Using a 16-bit linker, the object module that the assembly process created will link without error, but with a warning that the program has no starting address. For this code the lack of a starting address is no problem, but providing a starting address to eliminate the warning is also no problem. With this corrected the code will assemble and link OK, and when run under Windows 2000 will display the first prompt, but when a decimal digit 0-9 is entered NTVDM reports a problem with an illegal instruction. This happens because you are using the wrong method of terminating the program. Here is the code with my corrections:
;*****************************************
;* Programa: CONDIC3.ASM *
;*****************************************
.MODEL small
.STACK 512d
.DATA
;-----------------------------------------------------------------
; These all return error A2071: initializer magnitude too large
; for specified size, because a $ outside of quotes in interpreted
; and an address (the current value of the location counter), and
; a 16-bit address will not fit in a byte. The solution it to move
; the $ inside the quotes so it will be interpreted as an 8-bit
; character.
;-----------------------------------------------------------------
;msg1 DB "Entre um valor numerico positivo(de 0 ate 9): ", $
;msg2 DB "Valor impar", $
;msg3 DB "Valor par", $
;msg4 DB "Caractere invalido", $
msg1 DB "Entre um valor numerico positivo(de 0 ate 9):$"
msg2 DB "Valor impar$"
msg3 DB "Valor par$"
msg4 DB "Caractere invalido$"
.CODE
;------------------------------------------------------------
; To set a starting address, provide a label at the start of
; the code and add the label to the END directive.
;------------------------------------------------------------
start:
;---------------------------------------------------------------------
; For a .EXE program (models other than tiny) the DS segment register
; must be initialized so it points to the program's data segment.
; Without this DS points into the PSP, and your instructions that are
; supposed to access the program's data access gargage in the PSP.
;---------------------------------------------------------------------
mov ax, @data
mov ds, ax
Lea DX, msg1
Call escreva
Mov AH, 01h
Int 021h
Cmp AL, 030h
Jge erro
Cmp AL,03Ah
Jge erro
Sub AL, 030h
And AL, 01h
Jpe par
Jpo impar
par:
Lea DX, msg3
Call escreva
Jmp saida
impar:
Lea DX,msg2
Call escreva
Jmp saida
erro:
Lea DX,msg4
Call escreva
Jmp saida
saida:
;
mov ah, 0
int 16h
;-----------------------------------------------------------
; Int 20h is intended to be used to terminate .COM programs,
; and for it to work correctly CS must contain the segment
; address of the PSP, and for an .EXE program it does not.
;-----------------------------------------------------------
;Int 020h
mov ax, 4c00h
int 21h
escreva PROC NEAR
Mov AH, 09h
Int 021h
Ret
escreva EndP
;--------------------------------------------------------
; When MASM reaches the end of the file without finding an
; END directive it returns error A2088: END directive
; required at end of file. The fix should be obvious.
;--------------------------------------------------------
end start
Beyond this there is a problem in your code that checks the range of the input character.
Also, this is in the wrong forum, so I will be moving it the correct one shortly.
Sorry because i've posted at the wrong forum! :'(
But now i'm getting other errors, see:
C:\masm32\bin\ML /c /coff /Cp /nologo /I"C:\masm32\Masm32\Include" "C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm"
Assembling: C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm
C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.asm(61) : warning A4023: with /coff switch, leading underscore required for start address : start
C:\masm32\bin\Link @"C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\link.war"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/SUBSYSTEM:CONSOLE /RELEASE /VERSION:4.0 "/LIBPATH:C:\masm32\Masm32\Lib" "C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.obj" "/OUT:C:\Documents and Settings\Nathan\My Documents\Assembly\CONDIC3\CONDIC3.exe"
CONDIC3.obj : fatal error LNK1190: invalid fixup found, type 0x0001
Make finished. 2 error(s) occured.
And here is my code:
;*****************************************
;* Programa: CONDIC3.ASM *
;*****************************************
.MODEL small
.STACK 512d
.DATA
msg1 DB "Entre um valor numerico positivo(de 0 ate 9): ", 24h
msg2 DB "Valor impar", 24h
msg3 DB "Valor par", 24h
msg4 DB "Caractere invalido", 24h
.CODE
start:
Mov DS, AX
Mov DX,offset msg1
Call escreva
Mov AH, 01h
Int 021h
Cmp AL, 030h
Jge erro
Cmp AL,03Ah
Jge erro
Sub AL, 030h
And AL, 01h
Jpe par
Jpo impar
par:
mov DX,offset msg3
Call escreva
Jmp saida
impar:
mov DX,offset msg2
Call escreva
Jmp saida
erro:
mov DX,offset msg4
Call escreva
Jmp saida
saida:
Mov AH, 0
Int 16h
Mov AX, 4c00h
Int 21h
escreva PROC NEAR
Mov AH, 09h
Int 021h
Ret
escreva EndP
End start
Thanks,
Nathan Paulino Campos
ML can assemble 16-bit DOS code OK, but not with the command line that you are using. For a 16-bit DOS program you need a 16-bit linker. For MASM32 version 10 the 16-bit linker is named link16.exe and it is in the \masm32\bin directory. Here is a minimal batch file to assemble and link.
C:\masm32\bin\ml /c filename.asm
pause
C:\masm32\bin\Link16 filename.obj;
pause
Your code is missing the:
mov ax, @data
The @data predefined equate will be replaced with the name of the default data group, and ML will replace that with the segment address of the data segment. As it currently is, you are loading DS with whatever value happens to be in AX.
now, all you need is to use the right linker, Nathan
you are using the 32-bit linker and it will not work
in the masm32\bin folder, you should find link16.exe
if not, you can get one here...
http://website.masm32.com/microsoft/Lnk563.exe
lol - Michael beat me to it
Thanks for all, Michael and dedndave! :clap:
All is working now! :U