I've been trying to learn x86 assembly, but instead of learning to program, I've been struggling with INCLUDE libraries, and problems with MASM32 Editor and Visual Studio 2013 compilers fighting each other. I can't even get a simple DumpRegs directive to work for s*** sake:
; Program template
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
;INCLUDE C:\Irvine\Irvine32.inc
INCLUDE Irvine32.inc
.data
; declare variables here
.code
main proc
; write your code here
mov eax,5
add eax,6
call DumpRegs
invoke ExitProcess,0
main endp
end main
The errors in Visual Studio:
1>c:\Irvine\SmallWin.inc(11): error A2071: initializer magnitude too large for specified size
1>c:\Irvine\SmallWin.inc(11): warning A4011: multiple .MODEL directives found : .MODEL ignored
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations\masm.targets(50,5): error MSB3721: The command "ml.exe /c /nologo /EP /Sa /Sg /WX /Zi /Fo"Debug\SamZone.obj" /Fl"Project.lst" /I "c:\Irvine" /W3 /errorReport:prompt /Ta..\ch03\SamZone.asm" exited with code 1.
I don't know what to do. But I do know that I can never truly learn and blossom with masm knowledge until this is resolved. I've already wasted nearly two weeks on this issue, unable to test (and, consequently, unable to learn) basic masm syntax.
You are experiencing exactly what I experience every time I touch C++ - a complete mess. The fault is not with Masm, it's not your fault either, no, the culprits are Visual Crap and, to a lesser extent, Kip Irvine who cooks his own soup for his teaching.
My advice: Drop VS and the Irvine lib. Instead, use qEditor's Console build all menu and start with hello world proggies:
include \masm32\include\masm32rt.inc
.data
MyArray dd 25, 18, 23, 17, 9, 2, 6
HelloW$ db "Hello World", 0
.code
start:
xor ebx, ebx ; set two non-volatile
xor esi, esi ; registers to zero
.Repeat
add esi, MyArray[4*ebx]
inc ebx
.Until ebx>=lengthof MyArray
MsgBox 0, cat$(str$(esi), " is the sum"), offset HelloW$, MB_OK
exit
end start
Let me know if it works. If you want to see what the CPU does in this proggie, download Olly (http://www.ollydbg.de/version2.html) and extract it to \Masm32\OllyDbg\ollydbg.exe, then open your helloworld.exe and start hitting F8. Much better than dumpreg.
Quote from: jj2007 on February 03, 2016, 07:32:00 PM
My advice: Drop VS and the Irvine lib. Instead, use qEditor's Console build all menu and start with hello world proggies:
Ugh... what a waste of money. To make matters worse, I just scratched off the pearson highered code and activated it too, so Irvine's text book resale value is already lower :(
But I suppose I will have to just cut my losses and try QEditor's Console. It's also called MASM32 Editor, right?
However, there's one more problem. Every time I try to open a .asm file, Visual Studio automatically opens, and displays a text file copy of that same .asm file. I already asked this in my other thread, but didn't get an answer that was straight enough for my taste, so let me ask that same question again:
How do I get Visual Studio to shut up (and mind it's own C++ purpose business), and get the .asm file to compile where it needs to?
- open \Masm32\qeditor.exe
- copy the code I posted above, and paste it
- save the file as \Masm32\MyTest.asm (you need to specify the .asm extension)
- click menu Project/Console Build All
- check the output window for errors
- click menu Project/Run program
If that works, right-click in Explorer on MyTest.asm, then Open With, predefined program, pick qEditor. That should block Visual Crap from interfering with your asm dreams 8)
Bit messy with VS as said here (https://scriptbucket.wordpress.com/2011/10/19/setting-up-visual-studio-10-for-masm32-programming/)
I've been learning with just Hutch's masm32 download. Everything works wonderfully RedSkeleton. Its a really impressive piece of work. All the demos in the tutorials work. Just open them in QEditor and compile and link.
When I started out a couple months ago the first thing I struggled with was what you seem to be doing, i.e., figuring out how to print stuff. You know, anything. Hello, World, whatever. I've found I can use about a half a dozen ways to do it. Also. I compile from the command line a lot too. I do that with Visual Studio too in C++. I hate just about all Microsoft's Visual programming junk. Anyway, here is one of my early endeavors to show how to print stuff...
; C:\Code\MASM\Projects\Demo3>ml /c /coff /Cp Test3.asm
; C:\Code\MASM\Projects\Demo3>link /SUBSYSTEM:CONSOLE Test3.obj
include \masm32\include\masm32rt.inc
IncrOne proto iNum:DWORD
.data?
dwNumber dd ?
pNumber dd ?
.code
start:
mov dwNumber, 5
printf("dwNumber = %u\n",dwNumber)
printf("ADDR dwNumber = %u\n",ADDR dwNumber);
printf("OFFSET dwNumber = %u\n",OFFSET dwNumber);
lea eax, OFFSET dwNumber
printf("eax = %d\n",eax);
lea eax, OFFSET dwNumber
mov pNumber, eax
printf("pNumber = %u\n",pNumber);
lea eax, OFFSET dwNumber
mov pNumber, eax
push pNumber
call IncrOne
printf("eax = %d\n",eax);
invoke crt_getchar
exit
IncrOne proc pNum:DWORD
LOCAL dwNum:DWORD
printf("\nEntering IncrOne()\n")
printf(" pNum = %u\n",pNum)
mov eax, pNum
mov eax, [eax]
printf(" eax = %u\n",eax)
printf("Leaving IncrOne()\n\n");
mov eax, pNum
mov eax, [eax]
add eax, 1
ret
IncrOne endp
end start
dwNumber = 5
ADDR dwNumber = 4206832
OFFSET dwNumber = 4206832
eax = 4206832
pNumber = 4206832
Entering IncrOne()
pNum = 4206832
eax = 5
Leaving IncrOne()
eax = 6
You can see my assembler and link command lines at top. It ought to compile perfect in Hutch's QEditor too. If you do use the command line syntax just execute a PATH command filling in the path to masm32/bin on your box.
To be truthful, I don't know how anyone could produce a better include file set than what's found here.
i think Kip gives you a lot of help on his site, if you find and read the right pages :P
http://www.kipirvine.com/asm/ (http://www.kipirvine.com/asm/)
Quote from: jj2007 on February 03, 2016, 08:18:22 PM
If that works, right-click in Explorer on MyTest.asm, then Open With, predefined program, pick qEditor. That should block Visual Crap from interfering with your asm dreams 8)
Thanks so much :biggrin: I'm excited to finally get started.
Quote from: jj2007 on February 03, 2016, 07:32:00 PM
If you want to see what the CPU does in this proggie, download Olly (http://www.ollydbg.de/version2.html) and extract it to \Masm32\OllyDbg\ollydbg.exe, then open your helloworld.exe and start hitting F8. Much better than dumpreg.
I did that and I'm hitting F8, but nothing seems to be happening. Where do I need to look to view what's in the registers and flags?
********** Where do I need to look to view what's in the registers and flags? *********
You need to debug your prog in source mode.
Add /Zi /Zd options to the compiler (ml or jwasm).
Add /DEBUG /DEBUGTYPE:CV to the linker (Verify the syntax)
Then follow your prog,line by line in a debugger,you will see the values of the register and the compiled code.
If you prefer Visual Studio to do that:
http://masm32.com/board/index.php?topic=4489.msg47997#msg47997
a little help
Quote from: RedSkeleton007 on February 04, 2016, 05:20:26 PMI'm hitting F8, but nothing seems to be happening. Where do I need to look to view what's in the registers and flags?
Extract the attachment as \Masm32\makeit.bat, then use the Project/Makeit.bat command. Olly must sit in \Masm32\OllyDbg\ollydbg.exe, of course.
Quote from: jj2007 on February 05, 2016, 04:19:35 AM
Extract the attachment as \Masm32\makeit.bat, then use the Project/Makeit.bat command. Olly must sit in \Masm32\OllyDbg\ollydbg.exe, of course.
Still nothing happens. Am I not supposed to build and run my program first? And if I do get it to work, where are the registers and flags going to be displayed?
dowload OllyDbg - as i recall, installation is merely a matter of creating a folder and placing the program in it
you want to make Olly the "default just-in-time" handler
if you open Olly, there is an Options menu
under Debugging, Just-in-time - Set OllyDbg button
it takes care of it for you, and saves previous settings if you want to reverse it
now, any program that generates an exception will cause Olly to pop up
we generally insert
int 3
into the code where we want execution to generate an exception
Olly has a few different panes
one has your code
one has data
one has registers and stack trace
Olly keys...
Program reset Ctrl + F2
Close program Alt + F2
Open EXE file F3
Bring Olly to top Alt + F5
Step into F7
Animate into Ctrl + F7
Step over F8
Animate over Ctrl + F8
Run program F9
Execute till return Ctrl + F9
Execute till user code Alt + F9
Run trace into Ctrl + F11
Stop execution F12
Run trace over Ctrl + F12
Stop anim. or tracing Esc
my understanding is that Visual Studio has a debugger (never used it - lol)
i think it's WinDbg or something similar
maybe someone else can fill you in about how to use that one
Quote from: RedSkeleton007 on February 05, 2016, 05:24:36 AM
Quote from: jj2007 on February 05, 2016, 04:19:35 AM
Extract the attachment as \Masm32\makeit.bat, then use the Project/Makeit.bat command. Olly must sit in \Masm32\OllyDbg\ollydbg.exe, of course.
Still nothing happens. Am I not supposed to build and run my program first? And if I do get it to work, where are the registers and flags going to be displayed?
Build & run is done by the makeit.bat attached above. Open it in Notepad to see the details.
Quote from: jj2007 on February 03, 2016, 07:32:00 PMIf you want to see what the CPU does in this proggie, download Olly (http://www.ollydbg.de/version2.html) and extract it to \Masm32\OllyDbg\ollydbg.exe
See Dave's post for details. As a beginner, you really need only the F8 key.
Hi Red,
Here is a toy for you. You can display all 8 registers in console mode in MASM32 without needing the Irvine version.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.data?
value dd ?
.data
item dd 0
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
call reg_status
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
reg_status PROC
.data?
eax_ dd ?
ebx_ dd ?
ecx_ dd ?
edx_ dd ?
esi_ dd ?
edi_ dd ?
ebp_ dd ?
esp_ dd ?
.code
mov eax_, eax
mov ebx_, ebx
mov ecx_, ecx
mov edx_, edx
mov esi_, esi
mov edi_, edi
mov ebp_, ebp
mov esp_, esp
sub esp_, 4
print "eax = "
print hex$(eax_),"h",13,10
print "ebx = "
print hex$(ebx_),"h",13,10
print "ecx = "
print hex$(ecx_),"h",13,10
print "edx = "
print hex$(edx_),"h",13,10
print "esi = "
print hex$(esi_),"h",13,10
print "edi = "
print hex$(edi_),"h",13,10
print "ebp = "
print hex$(ebp_),"h",13,10
print "esp = "
print hex$(esp_),"h",13,10
ret
reg_status ENDP
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Output will look something like this.
eax = 749A3378h
ebx = 7EFDE000h
ecx = 00000000h
edx = 00401000h
esi = 00000000h
edi = 00000000h
ebp = 0018FF94h
esp = 0018FF80h
Press any key to continue ...
Here is a normal UI version that shows a MessageBox.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.data?
value dd ?
.data
item dd 0
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
call showregs
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
showregs PROC
LOCAL buffer[256]:BYTE
LOCAL pbuf :DWORD
.data?
eax_ dd ?
ebx_ dd ?
ecx_ dd ?
edx_ dd ?
esi_ dd ?
edi_ dd ?
ebp_ dd ?
esp_ dd ?
.code
mov eax_, eax
mov ebx_, ebx
mov ecx_, ecx
mov edx_, edx
mov esi_, esi
mov edi_, edi
mov ebp_, ebp
mov esp_, esp
sub esp_, 4
mov pbuf, ptr$(buffer)
mov pbuf, cat$(pbuf,"eax = ",hex$(eax_),"h",chr$(13,10),"ebx = ",hex$(ebx_),"h",chr$(13,10))
mov pbuf, cat$(pbuf,"ecx = ",hex$(ecx_),"h",chr$(13,10),"edx = ",hex$(edx_),"h",chr$(13,10))
mov pbuf, cat$(pbuf,"esi = ",hex$(esi_),"h",chr$(13,10),"edi = ",hex$(edi_),"h",chr$(13,10))
mov pbuf, cat$(pbuf,"ebp = ",hex$(ebp_),"h",chr$(13,10),"esp = ",hex$(esp_),"h",chr$(13,10))
fn MessageBox,0,pbuf,"Registers",MB_OK
ret
showregs ENDP
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
use PUSHAD to set up the stack frame :P
;----------------------------------------
_reg_eax TEXTEQU <DWORD PTR [EBP+32]>
_reg_ecx TEXTEQU <DWORD PTR [EBP+28]>
_reg_edx TEXTEQU <DWORD PTR [EBP+24]>
_reg_ebx TEXTEQU <DWORD PTR [EBP+20]>
_reg_esp TEXTEQU <DWORD PTR [EBP+16]>
_reg_ebp TEXTEQU <DWORD PTR [EBP+12]>
_reg_esi TEXTEQU <DWORD PTR [EBP+8]>
_reg_edi TEXTEQU <DWORD PTR [EBP+4]>
;----------------------------------------
pushad
push ebp
mov ebp,esp
;
leave
popad
ret
another version...
;----------------------------------------
_reg_eax TEXTEQU <DWORD PTR [EBP-4]>
_reg_ecx TEXTEQU <DWORD PTR [EBP-8]>
_reg_edx TEXTEQU <DWORD PTR [EBP-12]>
_reg_ebx TEXTEQU <DWORD PTR [EBP-16]>
_reg_esp TEXTEQU <DWORD PTR [EBP-20]>
_reg_ebp TEXTEQU <DWORD PTR [EBP-24]>
_reg_esi TEXTEQU <DWORD PTR [EBP-28]>
_reg_edi TEXTEQU <DWORD PTR [EBP-32]>
;----------------------------------------
push ebx
push esi
push edi
push ebp
mov ebp,esp
pushad
;
leave
pop edi
pop esi
pop ebx
ret
Hi, REDSKELETON007,
We here at the MASM Forum, get these kinds of questions alot. The answer is pretty simple, really,...
I have used Visual Studio over a period of years, for coding numerous C++ and Net Framework (C#) projects. It is a great IDE, but, to use it effectively, you must be aware of how its default mode operates, and, how to alter the various project settings, using the Project Properties Page. Here is the Microsoft MSDN Documentation: Working with Project Properties, MSDN (https://msdn.microsoft.com/en-us/library/669zx6zc.aspx). Unfortunately, when you alter the Project Properties, Visual Studio, saves this data and applies it to ALL PROJECTS that you open.
I've written many projects that compile MASM assembly language DLLs, and incorporate them with a C++ Visual Studio Project. This is not the default mode for Visual Studio, and so it doesn't work well to create the entire project with Visual Studio. The best way to do this is to write the source code for MASM assembly language component DLL and then compile it with MASM ml.exe (using the QuickEditor menu selection is the simplest and easiest way). Then write the rest of your project in C++ and compile it with Visual Studio, keeping the two components separate. Write your assembly language DLL so that it exports its routines, and write your C++ Visual Studio components so that it imports those routines into your Visual Studio project.
...Oh,...and also, the Irvine Library functions are a total pain in the ass,...they are designed so that they only work with other Irvine Library routines. This is a MAJOR source of error for novice MASM programmers.
Hello
I met this problem somedays ago, and I've already solved it.
TIPs:
If you include Irvine32.inc, DON'T include these code:
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD
(I don't know why I can't use the Insert Code function. Maybe because this is a new account?)
So try compiling this below. It is from Chapter 5 in Irvine's book
.data
COUNT = 4
BlueTextOnGray = blue + (lightGray * 16)
DefaultColor = lightGray + (black * 16)
arrayD SDWORD 12345678h,1A4B2000h,3434h,7AB9h
prompt BYTE "Enter a 32-bit signed integer: ",0
.code
main PROC
mov eax,BlueTextOnGray
call SetTextColor
call Clrscr
mov esi,OFFSET arrayD
mov ebx,TYPE arrayD
mov ecx,LENGTHOF arrayD
call DumpMem
call Crlf
mov ecx,COUNT
L1: mov edx,OFFSET prompt
call WriteString
call ReadInt
call Crlf
call WriteInt
call Crlf
call WriteHex
call Crlf
call WriteBin
call Crlf
call Crlf
loop L1
call WaitMsg
mov eax,DefaultColor
call SetTextColor
call Clrscr
exit
main ENDP
END main