News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Memory Reference Error

Started by nsharp, September 17, 2010, 05:48:05 AM

Previous topic - Next topic

nsharp

I am trying to learn assembly language programming through masm32.

My problem is this: even the simplest assembly language program, which I can think of, cannot be run.

The example that I am trying is this:

-----------------------------------

.486
.model small

.code
_start:
mov ax, bx
end _start

-----------------------------------------

I believe this is correct - because when I say Project --> Build All, it works fine and the .exe file is also created. The problem comes when I try to run this .exe file. The error message I get is this: The instruction at "0x00401003" referenced memory at "0x0000f000". The memory could not be "written".

(I cannot believe that I cannot refer to registers AX, BX, etc. because using the DOS Debug I can do things like "-r ax", "-r bx", etc. and also I do not understand why the error message says that I am trying to refer to a memory location, when I am trying to refer to registers AX and BX in the CPU. I appreciate it very much if an expert can explain these issues also to me)

I am trying to run the .exe file on the Windows XP (with Service Pack 2) - I have about 1GB RAM on my machine.

I have check the Data Execution Prevention (DEP) issue also, which I saw in forums while looking for a clue. I went to "My Computer" --> "Properties" --> "Advanced" --> "Performance" --> Settings" --> "Data Execution Prevention" and there I have two options. I tried both options (i.e. the first one being Turn on DEP for essential Windows programs and services only and the second one being Turn on DEP for all programs and services except those I select: test1.exe - test1.exe is the program that I am trying to run) I was asked to reboot the computer when I changed my options with DEP and I did that too. I believe it is not possible to turn off DEP on my machine and only these two options are available. I cannot run my .exe file with any of those options.

Any help at this stage is very much appreciated. How can I run this most simple assembly language program? thank you in advance.

BogdanOntanu

First of all decide yourself if you want to learn the old and kind of useless 16 bits ASM  programming (then this post should not be in this sub-forum)
OR if you want to learn the new 32 bits Windows or even the newest 64 bits Windows ASM programming.

IMHO for a beginner the "more accessible" and "easy" way is to start with 32 bits windows ASM and make use of MASM32 package.

Anyway you have very simple and functional windows ASM programs in this forums and in the examples folder in MASM32 package... I suggest that you study them.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

MichaelW

nsharp,

The main problem is that your source mixes a 16-bit memory model (.model small) with a 32-bit code segment (the default when a .386 or higher processor directive precedes the .model directive), and you are trying to create a 32-bit app from it.

eschew obfuscation

hutch--

Hi nsharp,

Welcome on board.


.486
.model small

.code
_start:
mov ax, bx
end _start


There are a number of things wrong with this, 32 bit code in Windows uses .model FLAT, the small memory model belongs to DOS.

The program does not terminate and requires a Windows API to do that.


    invoke ExitProcess,0


You can use the 16 bit registers as you have but you cannot use a 16 bit register to hold an address as 32 bit Windows requires a 32 bit register to do that.

It takes a bit of a brain shift to come from DOS to protected mode Windows but the gains are many and it is simpler clearer code.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

nsharp

Quote from: BogdanOntanu on September 17, 2010, 06:29:17 AM
First of all decide yourself if you want to learn the old and kind of useless 16 bits ASM  programming (then this post should not be in this sub-forum)
OR if you want to learn the new 32 bits Windows or even the newest 64 bits Windows ASM programming.

IMHO for a beginner the "more accessible" and "easy" way is to start with 32 bits windows ASM and make use of MASM32 package.

Anyway you have very simple and functional windows ASM programs in this forums and in the examples folder in MASM32 package... I suggest that you study them.

Thank you very much for the response but I should admit that I do not understand all that is said in that. For instance, only after I read that I was trying to do something 16bit, I realized it.

I regret if I have posted in the wrong sub-forum - but I thought Workshop is the sub-forum for beginners - not the campus or lab or collosseum. Sorry about that. I do not necessarily want to study anything 16 bit. But at the same time I do not want to start with various .inc files and .lib files which are included in the masm32 examples. I am a beginner and I do not understand much about things like windows.inc, user32.inc, kernel32.inc, user32.lib, kernel32.lib, etc. I want to start with simple things like moving data among registers, reading from the keyboard, writing to the screen, etc. I mean basically the command line stuff and not the things which depend on windows libraries. Can I not start with things like put two numbers in two registers, add them together, display the result on the screen, or read a character from the screen, change the case, display it on the screen, or read the name of the user from the keyboard, greet him or her with "Hello so and so"?. I may be wrong but as far as I know this is where I should start learning. I can later go to windows things like message boxes, etc. Any help regarding the kind of examples that I have mentioned above is perfectly very much appreciated. I do not mind doing them in the 32 bit fashion provided if it does not involve depending on others libraries, macros, procedures, etc. Do I have to restrict myself to 16 bit operations if I want to do the examples that I have mentioned above? I do not understand. Please help.

nsharp

Quote from: MichaelW on September 17, 2010, 06:49:22 AM
nsharp,

The main problem is that your source mixes a 16-bit memory model (.model small) with a 32-bit code segment (the default when a .386 or higher processor directive precedes the .model directive), and you are trying to create a 32-bit app from it.



Thanks for your response. But I am not yet able to get my .exe file running even though I learnt something from your response - thanks for that.

I had used .486 not because I understood it, but mainly because I saw it in an example. I changed it to .186, .286, .386, .586, .686 but did not work. When I tried this:

---------------------------------------

.286
.model small

.code
_start:
mov ax, bx
end _start

-----------------------------------------

I get the following error message:

test1.obj : warning LNK4078: multiple ".data" sections found with different attributes (C0220040)
ibutes (C0220040)

Then changed .small to .flat (I should admit that I had used .small only because I saw it in an example) but no result.

Then I got the following error message:


Assembling: C:\masm32\bin\test1.asm
C:\masm32\bin\test1.asm(2) : error A2085: instruction or register not accepted i
n current CPU mode
C:\masm32\bin\test1.asm(4) : error A2013: .MODEL must precede this directive
C:\masm32\bin\test1.asm(5) : error A2034: must be in segment block
C:\masm32\bin\test1.asm(6) : error A2034: must be in segment block
C:\masm32\bin\test1.asm(7) : error A2006: undefined symbol : _start
C:\masm32\bin\test1.asm(7) : error A2148: invalid symbol type in expression : _s
tart

Then I tried the following one:

---------------------

.486
.model flat

.code
_start:
mov ax, bx
end _start

----------------------------

.exe file was created but I get the following error message:

The instruction at "0x00401003" referenced memory at "0x00004000". The memory could not be "written".

All need is to put two values into two registers, add them together and display the result on the screen, without including any additional libraries, etc. in my code. How can I do that? Any help in this regard is very much appreciated.

nsharp

Quote from: hutch-- on September 17, 2010, 06:59:35 AM
Hi nsharp,

Welcome on board.


.486
.model small

.code
_start:
mov ax, bx
end _start


There are a number of things wrong with this, 32 bit code in Windows uses .model FLAT, the small memory model belongs to DOS.

The program does not terminate and requires a Windows API to do that.


    invoke ExitProcess,0


You can use the 16 bit registers as you have but you cannot use a 16 bit register to hold an address as 32 bit Windows requires a 32 bit register to do that.

It takes a bit of a brain shift to come from DOS to protected mode Windows but the gains are many and it is simpler clearer code.

I appreciate your reply. I put the code that you have mentioned at the end of my code but unfortunately it did not work.

I tried this

-------------------------

.486
.model flat

.code
_start:
mov ax, bx
end _start
invoke ExitProcess,0

---------------------------

I got the following error message when I tried to run the .exe file (.exe was create):

The instruction at "0x00401003" referenced memory at "0x00008000". The memory could not be "written".

ThenI tried this one also:

--------------------

.486
.model flat

.code
_start:
mov ax, bx
invoke ExitProcess,0
end _start

--------------------

but got the following error message (.exe was not create):

Assembling: C:\masm32\bin\test1.asm
C:\masm32\bin\test1.asm(7) : error A2006: undefined symbol : ExitProcess
_
Assembly Error
Press any key to continue . . .

All I need is to write a simple Assembly code to manipulate a few registers and see how it works. Here I am trying to put two values into two registers, say AX and BX and add them together and display the result on the screen. How can I just do that? I think if I can see how it can be done with DOS then it is better because I feel that doing it in the 32 bit windows fashion involves other functions, etc.

Thank you very much for your help

japheth

Quote from: nsharp on September 17, 2010, 07:41:59 AM
ThenI tried this one also:



.486
.model flat

.code
_start:
mov ax, bx
invoke ExitProcess,0
end _start



but got the following error message (.exe was not create):

Assembling: C:\masm32\bin\test1.asm
C:\masm32\bin\test1.asm(7) : error A2006: undefined symbol : ExitProcess
_
Assembly Error
Press any key to continue . . .

All I need is to write a simple Assembly code to manipulate a few registers and see how it works. Here I am trying to put two values into two registers, say AX and BX and add them together and display the result on the screen. How can I just do that? I think if I can see how it can be done with DOS then it is better because I feel that doing it in the 32 bit windows fashion involves other functions, etc.

Thank you very much for your help


Your last try is pretty good already, but, as you probably suspect, your source has references to the OS API and needs libraries.

You can get rid of this by changing your source to:



.486
.model flat

.code
_start:
mov ax, bx
ret
end _start


Thus your source can be assembled and linked and run without problems - but you won't see any output of course.

If you want to see your program working, but without having to study the Win32 API, I suggest to download the "Debugging tools for Windows". It's from MS and includes CDB, a Win32 equivalent of the good old DOS DEBUG. With this mini-debugger you will be able to launch your program, stop at program entry, watch current register values and more. It even contains - like DEBUG - a line assembler to create and execute instruction on the fly.

If you don't want to make yourself familiar with debugging tools, either learn the Win32 API or copy some code from sample programs to implement screen output. It's simple.


hutch--

Try this, it doesn't do anything but it builds correctly and shows you the very basics.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    .686p
    .model flat, stdcall                      ; 32 bit memory model
    option casemap :none                      ; case sensitive

    include \masm32\include\windows.inc       ; main windows include file
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

.code

start:

    mov eax, 1
    mov ecx, 2
    add eax, ecx

    invoke ExitProcess,0

end start

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

nsharp

thanks japheth!

Your solution works!!

Now I have at least a starting point to proceed.

nsharp

thank you hutch-- . I really appreciate your suport. The code you have given works propely. Not that I am alergic to Windows libraries. But at this stage I want to ensure, what I write is the simplest psosible code and I write the code I understand.

untio

Hi,
If you want to create a DOS program, you need to use the 21H interruption to terminate your program:

.MODEL SMALL
.286

.STACK 2048 ;I reserve 2048 bytes for the stack.

.CODE
_start:
MOV AX, BX
;I shall use the service 4Ch (in ah) of the 21h interruption of MSDOS.
;in al I put the value returned from the program.
MOV AX, 04C00H
INT 21H
end _start


I have executed it in an emulator and it works right. If it not contains the call to the interruption, the program hangs ms dos.

Please forgive my mistakes.

hutch--

nsharp,

The basic difference between a real mode 16 bit app and a 32 bit protected mode app is the real mode app can be written without OS level support if you know what you are doing where with a protected mode app you must use the OS functions to interact with the computer. In 16 bit DOS most used the DOS and BIOS interrupts which are just OS level functions addressed through the hardware interrupt instructions built into the processor.

A 32 bit app running under 32 bit Windows has a different architecture in that the basic functions of disk IO, memory access and the like are provided by the OS and there is no other way to do it as the OS blocks most direct hardware access.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

nsharp

Quote from: untio on September 17, 2010, 11:42:44 AM
Hi,
If you want to create a DOS program, you need to use the 21H interruption to terminate your program:

.MODEL SMALL
.286

.STACK 2048 ;I reserve 2048 bytes for the stack.

.CODE
_start:
MOV AX, BX
;I shall use the service 4Ch (in ah) of the 21h interruption of MSDOS.
;in al I put the value returned from the program.
MOV AX, 04C00H
INT 21H
end _start


I have executed it in an emulator and it works right. If it not contains the call to the interruption, the program hangs ms dos.

Please forgive my mistakes.


Thank you untio for your code. But unfortunately I could not properly build your code (I mean using Project --> Build All) because I get the following warning:

test14.obj : warning LNK4078: multiple ".data" sections found with different attributes (C0220040)

Why is that?

nsharp

Quote from: hutch-- on September 17, 2010, 12:21:45 PM
nsharp,

The basic difference between a real mode 16 bit app and a 32 bit protected mode app is the real mode app can be written without OS level support if you know what you are doing where with a protected mode app you must use the OS functions to interact with the computer. In 16 bit DOS most used the DOS and BIOS interrupts which are just OS level functions addressed through the hardware interrupt instructions built into the processor.

A 32 bit app running under 32 bit Windows has a different architecture in that the basic functions of disk IO, memory access and the like are provided by the OS and there is no other way to do it as the OS blocks most direct hardware access.

Thanks hutch-- for your continuing concern. Your post clarified one of my major doubts.

I believe the following code can only be run on DOS and not in the command line window of the Windows XP?

-------------------------------------
.286
.model small

.code
_start:
mov ax, bx
ret
end _start

--------------------------------

Am I correct?

Is it possible to use MASM32 on DOS or is MASM32 limited to using with Windows systems?