3

I am good with M68000 but X86 is diffficult for me. I am trying to assemble this simple program with MASM

.MODEL SMALL
.data?
  ONE  dB ?
  TWO  dB ?
  stack db  100 dup(?)

.data
  MSG  db 13,10, 'Enter deree of polynomials:  $'
  MSG2 db 13,10, 'Enter coefficient of x^ $' 
  MSG3 db 13,10, 'The polynomial created is: $'
  MSG4 db 13,10, 'The first derivative is: $'
  STR1 db  255 DUP('$')

.code

_start:

            mov ax, offset MSG
            mov ds, ax  

end _start

and I keep getting the error Unknown relocation type (1) for symbol MSG. I know what this is (it happens when the displacement is bigger than that allowed by the model or something like this) but I do not know how to solve this error (I know MASM is a 32 bit assembler and I am trying to write a 16 bit code). What I am trying to do is to load the pointer to .data into ds register.

My makeit.bat generated by the MASM32 IDE is:

@echo off
if exist "derivative 1.obj" del "derivative 1.obj" 
if exist "derivative 1.exe" del "derivative 1.exe" 
\masm32\bin\ml /c /coff "derivative 1.asm" 
if errorlevel 1 goto errasm 
\masm32\bin\PoLink /SUBSYSTEM:CONSOLE "derivative 1.obj" 
if errorlevel 1 goto errlink dir "derivative 1.*" goto TheEnd 
:errlink 
  echo _ 
  echo Link error 
  goto TheEnd 

:errasm 
  echo _ 
  echo Assembly Error 
  goto TheEnd 

:TheEnd 
  pause
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • Add also command line, how you invoke the MASM (will make bigger chance this will attract somebody with MASM knowledge to try it out). And you want to load into `ds` the `SEGMENT` part of address, not `OFFSET`. I.e. `mov ax, segment MSG` `mov ds,ax` `mov bx, offset MSG` => `ds:bx` contains complete segment:offset representation of the 20 bit physical memory address. Although from the error it looks like something more fundamental about your MASM setup is wrong, maybe treating that source as 32/64b, because what you wrote should compile in 16b, it just doesn't make sense. – Ped7g Nov 22 '17 at 16:09
  • There is no command line, i assemble it from MASM with makeit.bat(it is an IDE command) – Valentin Bogatu Nov 22 '17 at 16:11
  • `makeit.bat` is DOS batch file (similar to unix shell scripts). You can open it in text editor to see what commands are invoked and with which arguments. "from MASM" .. wait, MASM is just assembler, you can't be "in it", do you mean Visual Studio? Then you can still check with some flags which commands are invoked. I can't be specific, as I didn't see Microsoft products over 10 years, I'm already fully migrated to linux and other *NIX systems, where these things are simple to do (as long as you don't mind different assembly syntax, I personally prefer NASM). Posting versions may help... – Ped7g Nov 22 '17 at 16:35
  • yes I know I can edit a .bat file, I just copied it to C: and it does not let me edit it. – Valentin Bogatu Nov 22 '17 at 16:51
  • C:\>type makeit.bat @echo off if exist "derivative 1.obj" del "derivative 1.obj" if exist "derivative 1.exe" del "derivative 1.exe" \masm32\bin\ml /c /coff "derivative 1.asm" if errorlevel 1 goto errasm \masm32\bin\PoLink /SUBSYSTEM:CONSOLE "derivative 1.obj" if errorlevel 1 goto errlink dir "derivative 1.*" goto TheEnd :errlink echo _ echo Link error goto TheEnd :errasm echo _ echo Assembly Error goto TheEnd :TheEnd pause – Valentin Bogatu Nov 22 '17 at 16:52
  • Yes, thank you, I have to link it with link16 or use this program WinAsm WinAsm is very simple and allows for 16 bit appications to be assembled fast – Valentin Bogatu Nov 24 '17 at 14:02

3 Answers3

5

The MASM32 package doesn't come with support for 16-bit executable generation, although it's not difficult to alter this behaviour. The MASM assembler in the MASM32 package will generate 16-bit code but the linkers supplied will not generate 16-bit executables. This results in the type of error(s) you are seeing.

You can download a copy of an older linker that supports 16-bit targets. I've made link16.exe (version 5.60.339 Dec 5 1994) available for download on my server.

Place link16.exe into the \masm32\bin directory. You will have to modify the generated makeit.bat file. The line that calls the linker (like link.exe or polink.exe) has to be replaced with:

\masm32\bin\link16.exe "filename.obj" ;

filename.obj is the name of the file you want to link. Change it to suit your project. The semicolon on the end will default all the file names and won't prompt for them. You will then have to modify the the ml line in makeit.bat so that it doesn't produce coff files. To do that remove /coff option:

\masm32\bin\ml /c "filename.asm"

Again filename.asm can be replaced by the name of the file in your project.


Other Observations

Once you are able to generate a 16-bit executable some issues with your code:

  • Remove stack db 100 dup(?) and use the .stack directive instead

    .stack 100h
    
  • You need to set up the segment value of MSG in DS instead:

    mov ax, seg MSG
    mov ds, ax 
    

    With the .small model there is only one data segment. In the .small model .data and .data? will be combined into a single .data segment. With this memory model you can also initialize DS this way:

    mov ax, @data
    mov ds, ax
    
  • For an DOS EXE program you'll need to exit with something like the DOS exit interrupt

    mov ax, 4c00h
    int 21h
    

If you are using MASM32 on a 64-bit version of Windows you wil not be able to directly run the 16-bit applications you create. You will have to download an emulator like DOSBox to run it, or install Virtual Machine (VMWare, VirtualBox, QEMU etc) software with a version of DOS/Windows that can run the code.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
0

For 16 bit assembly, with dot directives (like .model, .data, .code) the syntax is:

        mov     ax, @data
        mov     ds, ax
rcgldr
  • 27,407
  • 3
  • 36
  • 61
  • mov ax, @data I receive the error undefined symbol: DGROUP someone says to play with the MODEL – Valentin Bogatu Nov 22 '17 at 16:22
  • Yeah, it works for 16 assembler. I'm looking into this. – rcgldr Nov 22 '17 at 16:22
  • The assembly error can be fixed in the batch file by using command line option /omf: `ml /c /omf example.asm`, but I'm not sure how to get 16 bit link output. – rcgldr Nov 22 '17 at 16:36
  • @ValentinBogatu - I could only get this to work with 16 bit linker. In my case, I have a full set of 16 build tools. You may be able to find and download a copy of the 16 bit tool set Visual C/C++ 1.52c. Visual C/C++ 1.52c is also included with the 32 bit tool set Visual C/C++ 4.1, but that will be harder to find. – rcgldr Nov 22 '17 at 16:52
  • I'll try to find an online 16 bit assembler. :) – Valentin Bogatu Nov 22 '17 at 17:03
  • @ValentinBogatu if you don't have some very strong reason why MASM (i.e. you plan to use MASM macros and quirk syntax, or you have some good book using MASM syntax), you can use NASM or FASM for windows (both have slightly different syntax, but reasonably close to MASM, and when they differ, they are usually closer to the original hazy Intel design used in Intel docs). – Ped7g Nov 22 '17 at 17:26
  • @ValentinBogatu - "16 bit assembler" - see if you can find a copy of MASM 6.11 (ML.EXE). It's a 16 bit assembler (also supports 32 bit assembly), but ML.EXE is a 32 bit program using a dos extender if running in real 16 bit MSDOS, or runs in a Windows 32 bit console window. It includes some other stuff like programmer's workbench (text base IDE), and codeview (text based source level debugger). – rcgldr Nov 22 '17 at 23:22
0

To all that gave me answers to the simple question above I am saying Thank you. Indeed the answer to my question is that the link16.exe is necessary to generate the 16 bit code. Another way I could assemble simply and fast my code was using WinAsm wich is an older IDE that I found by googling.