NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: sledge on August 08, 2011, 09:11:09 PM
-
I'm reading an assembly online book (PC ASSEMBLY by Paul Carter), and after going thru the first two chapters I decided do some practice. But the problem is, this (which is very well written by the way) is a tutorial on how to program asm using NASM on a 32bit machine, and I'm using a 64bit with Windows 7. Can I practice whats written in that book even though I'm using a different machine than the one specified in the book? Maybe I should download DOSBOX so I can simulate a real x86 so I can practice?
-
It should work, I think. The examples with Dr. Carter's tutorial use C to communicate with the OS. So the question becomes, what C compiler/library are you using, or would you like to use? I don't think Dr. Carter's 32-bit asm code (or yours) would play nicely with a 64-bit compiler/library, but you should be able to tell such a compiler to do 32-bit code, I think. I don't know the command line switches you'd use for Windows compilers to do that, but I imagine they'll do it. Microsoft or OpenWatcom compilers should work for you - I'm less sure about DJGPP. The Borland compiler is getting pretty old, but should work still. The resulting 32-bit programs should run fine on your 64-bit system, AFAIK. Let us know how it goes!
Best,
Frank
-
And what if I use DosBox? Will it simulate a Dos OS as if my computer was a real x86 running DOS? That way, can I practice with Dr Carter's document following the exact same code that the tutorial displays?
-
And what if I use DosBox? Will it simulate a Dos OS as if my computer was a real x86 running DOS? That way, can I practice with Dr Carter's document following the exact same code that the tutorial displays?
Yup, I was surprised myself how well DOSBOX works and how much it is capable simulating a real X86 machine.
I even use it instead of BOCHS often, it's faster. Not saying it's even remotely capable emulating everything as BOCHS.
But, you know, one didn't expect that much from a simple "DOS emulator". It can deal with quiet alot.
Anyways; everything important, including processor and much of the hardware around it.. is emulated in DOSBOX.
You could safely enjoy your "x86 machine", on both 32- and 64-bits systems :)
-
In case you haven't given this idea a thought: Use VirtualBox (http://www.virtualbox.org) to create a DOS VM for your practicing. I use it extensively for developing and testing Linux x86 & x64 programs. My host is a quadcore Win7 x64 system and I've never had any issues uses it. Highly recommended! 8)
-
Thank you both for your answers. I'm glad there's a solution for my studies without having to use a 32bit machine.
In case you haven't given this idea a thought: Use VirtualBox to create a DOS VM for your practicing. I use it extensively for developing and testing Linux x86 & x64 programs. My host is a quadcore Win7 x64 system and I've never had any issues uses it. Highly recommended
Good idea, isnt Virtual Box the same as DosBox? I'll do some research and install both softwares on my machine, thanks again.
-
Good idea, isnt Virtual Box the same as DosBox? I'll do some research and install both softwares on my machine, thanks again.
They are as different as night and day. VirtualBox supports almost every imaginable guest x86 or x64 operating system on the planet ( if the guest OS was designed to run on a PC, that is ). It is not an emulator but rather virtualizes the hardware to present to the guest OS a machine it "thinks" it's installing/running on.
It is the equivalent to VMWare but much better IMHO. And it's FREE.
No, I don't work for Oracle :P
-
I'm back with new issues. I downloaded the DOS version of nasm (nasm-2.09-dos-upx.zip) and then mounted the extracted directory on DosBox. After using google for a sample code, I created a test.asm with (and saved it on the directory that was about to be mounted in dosbox):
; hello.asm a first program for nasm for Linux, Intel, gcc
;
; assemble: nasm -f elf -l hello.lst hello.asm
; link: gcc -o hello hello.o
; run: hello
; output is: Hello World
SECTION .data ; data section
msg: db "Hello World",10 ; the string to print, 10=cr
len: equ $-msg ; "$" means "here"
; len is a value, not an address
SECTION .text ; code section
global main ; make label available to linker
main: ; standard gcc entry point
mov edx,len ; arg3, length of string to print
mov ecx,msg ; arg2, pointer to string
mov ebx,1 ; arg1, where to write, screen
mov eax,4 ; write sysout command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov ebx,0 ; exit code, 0=normal
mov eax,1 ; exit command to kernel
int 0x80 ; interrupt 80 hex, call kernel
And then, on dos box, I entered: nasm test.asm.
Dosbox then displayed: Cannot open swap file.
I attached a screen picture on this post for more details.
-
Perhaps I should have spoken up sooner. While I think installing Dosbox is probably useful, Dr. Carter's code is not for dos (can be used with a "dos extender" - DJGPP, e.g.). More to the immediate point, your example "hello" is for Linux, not dos. "int 80h" is Linux, "int 21h" (among others) is for dos.
A sample "hello.asm" -> "hello.com" suitable for dos would be:
; nasm -f bin -o hello.com hello.asm
; no linking needed
; this does not "cause" our program to
; be loaded at 100h, but informs Nasm that
; our file will be loaded by dos at 100h.
; important for calculating where "msg" will be.
org 100h
; the subfunctions of int 21h go in ah
; 9 writes a $-terminated string
mov ah, 9
; the address/offset of the string goes in dx
mov dx, msg
int 21h
; the 4Ch subfunction exits back to dos
mov ah, 4Ch
int 21h
msg db "Hello, world!", 13, 10, '$'
That's "from memory", but pending typos, should be right(?).
If you can get that working, we can get on to getting set up to run some of Dr. Carter's examples. If you want to be able to run Linux, I understand "andLinux" would allow it, but "one thing at a time"...
Best,
Frank
-
It worked like a charm. ;D It printed 'hello world' when I typed the com file on dos. Cool!
Now I'll do some research to make the compiler work with the C driver so I can code programs to use functions like printf from C etc...
Btw what if I dont inform dos to load my code at 0x100? What point of memory will it load at? Well, I'll try first and ask later, thank you!
-
Dos will load your program at 100h... because that's what it does with a .com file (determined by the lack of an "MZ" signature - you could name it ".exe" and it would still be a .com file!). The "org 100h" merely tells Nasm that this is true, so it can calculate the address of "msg" correctly. Try it without the "org 100h". Then try:
mov dx, msg + 100h
You could try "org 80h" and "msg + 80h", too. That's what "org" does for us...
When we type "hello", dos finds a free segment and builds a "Program Segment Prefix" of 256 (100h) bytes. The first half of this "PSP" contains some information, some of which is "interesting"... the segment where the environment variables can be found, for example. The upper half serves as a "buffer" - if we type "hello one two three", the "one two three" will appear there, and it's used a a default "Data Transfer Area" for "directory" functions "findfirst" and "findnext".
Our program is loaded after that. The chosen segment is loaded into the segment registers, a word (two bytes) zero is pushed on the stack, and execution jumps to cs:100h. We're on!
I showed you to exit via int 21h with 4Ch in ah. Another way to do it would be with int 20h. Another way to do it is "ret". "ret" takes its return address (to return to) off the stack. Dos pushed a zero there, remember, so we "ret" to... the beginning of the PSP. The first two bytes of the PSP are CDh, 20H - int 20h - so we're still using int 20h to exit, not really "returning" to dos...
Dos is fun to play with, and can be educational, but there isn't a lot of "commercial potential" to it, these days. You probably want to get on to 32-bit code fairly soon...
Dr. Carter's "driver.c" just calls "asm_main" (a label declared "global" in our asm code so the linker can find it). "asm_io.asm" will have to be assembled first into "asm_io.obj". You'll have to define "OBJ_TYPE" on Nasm's command line, I think... It contains the functions "print_int", "read_int", etc. The file "asm_io.inc" which has to be "%include"ed in our code, takes care of declaring "print_int" etc. as "extern", so we can just go ahead and use them freely without having to worry about it. It also provides a few useful macros like "dump_regs"...
Once you've got DJGPP installed, it should go pretty smoothly. (one can hope...)
Best,
Frank