Hi;
Our teacher uses a syntax like this simple example for teaching assembly:
.MODEL SMALL
.386
.DATA
X DB 3
.CODE
.STARTUP
MOV AL,5
ADD AL,X
.EXIT
END
I tried this for MASM:
.MODEL SMALL
.386
.DATA
X DB 3
.CODE
main:
MOV AL,5
ADD AL,X
end main
.EXIT
END
But MASM doesn't assemble this. :(
What's the problem?
He usually uses emu8086 but it's a bit old and I want to do this with MASM.
Quote from: sb1370 on April 28, 2013, 05:26:43 PM
But MASM doesn't compile this. :(
Masm is not a compiler, it's an assembler. And it does
assemble your snippet. Probably (can't read your thoughts, can't see your error messages) you'll see complaints from the
linker. Are you using \Masm32\bin\link16.exe ?
Quote from: sb1370 on April 28, 2013, 05:26:43 PM
But MASM doesn't compile this. :(
What's the problem?
The more important question that you should ask yourself is why you want to remove .STARTUP and .EXIT. Because these directives are there
for a good reason and they can't just be removed without causing your program to crash when it's launched.
QuoteHe usually uses emu8086 but it's a bit old and I want to do this with MASM.
Masm is most likely older than emu8086.
it does assemble using MASM, although both versions have little problems :P
both versions use a .END directive, but do not reference the entry point
your version doesn't initialize the DS register, nor does it terminate properly
as Jochen mentioned, this is 16-bit code and will build if you use a 16-bit linker
i have never used the .STARTUP or .EXIT directives, so i was curious to see exactly what they do
i figured the .STARTUP directive sets the DS register and .EXIT terminates with INT 21h
well, i was half-right :P
.EXIT generates the following code, at least when the SMALL model is specified
mov ah,4Ch
int 21h
it may generate something different if the TINY model is specified
the code generated by .STARTUP was a little more surprising
again, this is for a SMALL model program and it undoubtedly generates something different for other models
mov ax,@data
mov ds,ax
mov bx,ss
sub bx,ax
shl bx,4
mov ss,ax
add sp,bx
the first 2 lines are pretty simple
they load the data segment into AX, then into DS - very common code for 16-bit EXE's
the rest of the code forces the SS register to reference the same segment as the DS register
a bit of a mystery for a beginner, probably
but it's forcing the .DATA segment and .STACK segment into a single GROUP
not really sure why they do that - it isn't necessary, in many cases
personally, i would write the program to look something like this...
;###############################################################################################
.MODEL SMALL
.386
;###############################################################################################
.DATA
X db 3
;###############################################################################################
.CODE
;***********************************************************************************************
_main PROC FAR
mov ax,@data
mov ds,ax
MOV AL,5
ADD AL,X
mov ah,4Ch
int 21h
_main ENDP
;###############################################################################################
END _main
i would also add a couple other directives, but that's beyond what the teacher wants
you could replace the first 2 lines of code with .STARTUP and the last 2 with .EXIT, just to make him happy :P
_main PROC
.STARTUP
MOV AL,5
ADD AL,X
.EXIT
_main ENDP
the program doesn't appear to do much when you run it
but, it does return an exit code of 8 (5+X), that could be accessed in a batch file with ERRORLEVEL commands
I think DGROUP and various other details of the segment structure were required if "programs compiled by Microsoft translators are to run properly" (quote from The MS-DOS Encyclopedia, Microsoft Press, 1988). The DS=SS allows you to change the value of DS without having to preserve the old value, and in a program with an interrupt handler readily access the program's near data from the handler.
yah - that directive may also alter the SS segment ASSUME
that wouldn't be evident in the disassembled code, but they probably reference DGROUP
Thanks for your answers.
I use Visual Studio 2012 as IDE with this trick:
http://www.codeproject.com/Articles/271627/Assembly-Programming-with-Visual-Studio-2010-2012
I tried the teacher code and it returned these errors;
error A2074: cannot access label through segment registers
error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\test.obj" /W3 /errorReport:prompt /Tatest.ASM" exited with code 1.
And I tried your code which returned these errors:
error A2006: undefined symbol : DGROUP
error A2074: cannot access label through segment registers
error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\test.obj" /W3 /errorReport:prompt /Tatest.ASM" exited with code 1.
I tried this code.
.MODEL SMALL
.DATA
.CODE
main:
MOV AX,5
ADD AX,5
end main
.EXIT
END
It assembles but while debugging this message is shown:
ASM1.exe has triggered a breakpoint.
I tried teacher's code on emu 8086 and it executed without any problem. I think emu8086 uses FASM assembler.
Quote from: sb1370 on April 28, 2013, 11:44:42 PM
And I tried your code which returned these errors:
error A2006: undefined symbol : DGROUP
error A2074: cannot access label through segment registers
Try again with /omf in the assembler's commandline (it works, just tested).
Quote from: sb1370 on April 28, 2013, 11:44:42 PM
I use Visual Studio 2012 as IDE with this trick:
http://www.codeproject.com/Articles/271627/Assembly-Programming-with-Visual-Studio-2010-2012
The article makes no mention of 16-bit code.
If I take the first source that you posted and assemble it, using ML 6.15, with:
ML /W3 /c test.asm
And link, using the 16-bit linker from the MASM32 distribution, with:
Link16 test;
Then the only problem is a no stack segment warning from the linker, which in this case can be safely ignored, or can be eliminated by adding a .STACK directive to the source.
If I take the same source and try to assemble it with a very normal command line for 32-bit code:
ML /W3 /c /coff test.asm
Then I get:
test.asm(6) : error A2006: undefined symbol : DGROUP
test.asm(8) : error A2074: cannot access label through segment registers
Your problems here have a solution that should be obvious. To edit the source you can use any workable editor, notepad is handy, and to compile and link you can use a batch file.
And if your program needs to access its data you are going to need to set a segment register so it points to the data segment, and if you expect to do the access without a segment override the segment register needs to be DS. The .STARTUP directive provides an easy way to do this, and it also establishes the program entry point as the location of the directive. And while there are multiple ways of terminating the program, the .EXIT directive provides an easy way to do it correctly.
It appears that the OP is using a higher version of ML.exe, therefore my suggestion to add /omf.
I tried /omf option. Now I get this error:
error LNK1107: invalid or corrupt file: cannot read at 0x1CF
first, try and build it without the debug switches
i am not sure how useful those symbols will be for a 16-bit file, anyways
also, be sure you are using LINK16.EXE, not LINK.EXE
ml /c /omf Tatest.asm
link16 Tatest.obj;
notice the semicolon at the end of the link16 line
i get the following warning from masm
Quotestart address ignored with .STARTUP
that's ok - the OBJ is still created
i get the following warning from link
Quotewarning - no stack segment
it seems to build the EXE, anyways
let's correct those warnings
.MODEL SMALL
.STACK
.386
;###############################################################################################
.DATA
X DB 3
;###############################################################################################
.CODE
;***********************************************************************************************
_main PROC
.STARTUP
MOV AL,5
ADD AL,X
.EXIT
_main ENDP
;###############################################################################################
END
now, it builds without any problems using the above command lines
Sorry for coming back late.
Thanks for your answers. I read your solution weeks ago but I was busy with my exams.
By the way with your solution I have two problems:
I can't set visual studio to use linker16. I downloaded MASM and extracted, renamed linker16 to linker copied it to visual studio folder, but linker16 need ';'. I couldn't set visual studio to use ';' after filename.
Also I use Windows 8 x64 edition so I can't run 16bit program natively .
What change I should do to make my codes to be compiled in 32bit?
your teacher is going to have to keep up with the times - lol
there are probably many students that are using 64-bit OS's
this should assemble, provided you have installed the masm32 package
;###############################################################################################
.XCREF
.NoList
INCLUDE \Masm32\Include\Masm32rt.inc
.List
;###############################################################################################
; .DATA
;***********************************************************************************************
; .DATA?
;###############################################################################################
.CODE
;***********************************************************************************************
_main PROC
mov eax,5
add eax,5
print str$(eax),13,10
inkey
INVOKE ExitProcess,0
_main ENDP
;###############################################################################################
END _main
To be clear, the 16-bit linker is not a 16-bit program. Terminating the link16 command line with a semicolon tells it to use the defaults for the remainder of the fields, instead of prompting you for the names.
The command line syntax is:
LINK16 <objs>,<exefile>,<mapfile>,<libs>,<deffile>
You can do without the semicolon and avoid the prompts by specifying all of the required fields. So for example to link test.obj and create test.exe and test.map, without specifying a LIB or DEF file, you could use:
LINK16 test, test, test, nul, nul
And the linker would add the appropriate extensions and ignore the libs and deffile fields. And other syntaxes are possible, for example:
LINK16 test, test, test,,,
My OS is 64bit so I cant debug my apps with Visual Studio.
Maybe I need to install Visual Studio on a virtual machine with 32bit OS.
I found MASM 6.11 with Programmers workbench but I couldn't create any .exe it gives error even with default settings.
I'm writing my assignment project in emu8086. It has good debugging features but it seems that it has some bugs. :icon_confused:
did you try installing the masm32 package ?
the link is in the upper right corner of the forum page
Yes, But I need an IDE with debugger.
Used WinASM on virtual machine. But couldn't find a good debugger.
By the way I took its exam today. ::)
i don't use an IDE :P
i think i would try RadAsm, if i wanted one
for a debugger, i use Olly v2
http://www.ollydbg.de/version2.html (http://www.ollydbg.de/version2.html)