VOGONS


First post, by Guld

User metadata
Rank Newbie
Rank
Newbie

Hey everyone, I've recently taken upon myself to go through some of my really old books and learn x86 assembly...for "fun" 😀. In any event, I am following the instructions in "Compute!'s Beginner's Guide to Machine Language on the IBM PC and PCjr". Their very first program just swaps some data around in memory and you are supposed to use the DOS debugger to look at the results.

So, I managed to get MASM to compile and link the program just fine. The executive looks alright, if I look at it in HxD I can see the data in the correct memory locations, etc. and the instructions seem correct. But when I run the program, it never returns back to DOS (Dosbox in this case).

Following the instructions from the book, I've also attempted to get DEBUG working in DOSBox (DOS debug, not DOSBoxes debug).
I tried to run DEBUG.EXE from IBM DOS 5.0, when I do, I never get the debugger '-' prompt, nor does it crash, it just seems to lock up.
I can run DEBUG.COM from IBM DOS 3.3 (by running "ver set 3 30" at the dosbox prompt), however unassembling the code via the 'U' command doesn't look like the correct data, and running the program via 'G' acts like running the program at the command line and doesn't reach normal program termination.

The code is listed below in case maybe I've put something in wrong?

Dosbox 0.74-3
machine = pcjr
all other settings are default I believe.

Any help would be greatly appreciated. If I get time I'll also try running this on my PCjr to see what it does there but I'd like to be able to mess with this under DOSBox just for simplicity sake. Or is there a better DEBUG tool I should be using for old DOS programs which works better? I presume that Visual Studio 2020 will not work with these old assembly programs.


; SWITCH.ASM
;
; Reverses an eight byte buffer. DEBUG
; must be used to analyze the results
; This program should work in any
; MS-DOS computer
;
; Marc Sugiyama 8/15/84
;
page ,96
;
data segment ; segment which holds buffers
source db 1,3,5,7,11,13,17,19 ; source buffer
dest db 0,0,0,0,0,0,0,0 ; empty destination buffer
data ends
;
stack segment stack ; stack segment
dw 128 dup (?) ; give the stack 256 bytes
stack ends
;
code segment ; segment for code
switch proc far ; for proper return to DOS
assume cs:code,ds:data,ss:stack
;
push ds ; set up for FAR RETurn to DOS
mov ax,0
push ax
;
mov ax,data ; set up DS for data segment
mov ds,ax
;
mov si,0 ; first byte of source data
mov di,15 ; last byte of desination area
move_bytes:
mov al,[si] ; move from source to AL
mov [di],al ; move from AL to destination
sub di,1 ; reduce dest pointer by one
add si,1 ; increase source pointer by one
cmp si,8 ; moved all of the bytes?
jne move_bytes ; if not, do more.
;
ret ; return to DOS
;
switch endp ; end of procedure declaration
code ends ; end of code segment
end ; end of program

Reply 1 of 9, by Guld

User metadata
Rank Newbie
Rank
Newbie

Also, if it helps, here is the output I see when unassembling with DOS 3.3 DEBUG.COM. As you can see, it does not look correct. However, looking at the EXE with HxD seems to look correct, or at least more believable than this.


-u

2409:0000 0103 ADD [BP+DI],AX
2409:0002 05070B ADD AX,0B07
2409:0005 0D1113 OR AX,1311
2409:0008 0000 ADD [BX+SI],AL
2409:000A 0000 ADD [BX+SI],AL
2409:000C 0000 ADD [BX+SI],AL
2409:000E 0000 ADD [BX+SI],AL
2409:0010 0000 ADD [BX+SI],AL
2409:0012 0000 ADD [BX+SI],AL
2409:0014 0000 ADD [BX+SI],AL
2409:0016 0000 ADD [BX+SI],AL
2409:0018 0000 ADD [BX+SI],AL
2409:001A 0000 ADD [BX+SI],AL
2409:001C 0000 ADD [BX+SI],AL
2409:001E 0000 ADD [BX+SI],AL
-q

Reply 3 of 9, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I suspect the RET is sending execution to the start of your code or data segments, resulting in an infinite loop or crash. Terminating with a RET instruction is normally used only in COM format where the PSP segment and code segment are the same. It seems you are compiling for EXE format, so I suggest using INT 21h function 4Ch to terminate.

Reply 5 of 9, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Perhaps the "switch proc far" directs a RETF to be assembled instead of a RET, but not sure if that works or if it's the correct syntax. Still, INT 21h/4Ch is the standard for EXE termination, as it does not require any management of the stack to work properly.

Reply 6 of 9, by Guld

User metadata
Rank Newbie
Rank
Newbie

Okay, I had some more time to tinker around. I'm still very new to x86 assembly (I've got TONS of experience with many other languages, even MIPS assembly, but not x86, 🤣), so I only vaguely understand the comments.

I was able to get the program to work correctly. I had to switch to a different version of MASM. I switch to "IBM Macro Assembler 2.0 (5.25)" from Winworldpc and that program works correctly and shows up as expected when I unassemble under the DOS 3.3 debugger. I have no idea why the other version I was attempting to use was not working correctly.

I still haven't gotten the DOS 5.0 DEBUG.EXE executive to run though. Although I may need to make sure I'm using a correct copy as all I did is pull the DEBUG.EX_ from the DOS 5 install disk and rename it. It looks like a size file I would expect, but who knows, maybe the DOS 5 setup program actually modifies it somehow. Unfortunately setting that up would take a little bit more effort as DOS 5 doesn't work on my PCjr without patching the binaries. Not too hard, but not sure I have time.

I may also look into using a debug build of Dosbox and use it's built in debugger, maybe that would be a good way for me to learn to use that. Any suggestions?

Reply 7 of 9, by VileR

User metadata
Rank Oldbie
Rank
Oldbie

Try the enhanced DEBUG found here: https://sites.google.com/site/pcdosretro/enhdebug (download link at the bottom). Works just fine in DOSBox without jumping through any hoops, but still fully compatible with DOS's DEBUG.EXE.

I'd definitely recommend looking into DOSBox's built-in debugger anyway, as it's more powerful and more convenient. But use-cases may differ - I still find DEBUG more useful for small ad-hoc tasks, like assembling a short block of code in-place, examining how it's encoded in machine language, and saving the result as a .com program.
If you go by the book, you might want to go through the exercises with DEBUG first, then try carrying out the same tasks in the DOSBox debugger to learn the ropes and get the hang of both tools.

Keep in mind: if you use a DOSBox debug build, the built-in debug command starts the internal debugger. So if you want to be able to run DOS's DEBUG.EXE as well (or the enhanced DEBUG.COM above), you'll need to rename them.

[ WEB ] - [ BLOG ] - [ TUBE ] - [ CODE ]

Reply 8 of 9, by Guld

User metadata
Rank Newbie
Rank
Newbie
VileR wrote on 2022-03-05, 08:31:
Try the enhanced DEBUG found here: https://sites.google.com/site/pcdosretro/enhdebug (download link at the bottom). Works just […]
Show full quote

Try the enhanced DEBUG found here: https://sites.google.com/site/pcdosretro/enhdebug (download link at the bottom). Works just fine in DOSBox without jumping through any hoops, but still fully compatible with DOS's DEBUG.EXE.

I'd definitely recommend looking into DOSBox's built-in debugger anyway, as it's more powerful and more convenient. But use-cases may differ - I still find DEBUG more useful for small ad-hoc tasks, like assembling a short block of code in-place, examining how it's encoded in machine language, and saving the result as a .com program.
If you go by the book, you might want to go through the exercises with DEBUG first, then try carrying out the same tasks in the DOSBox debugger to learn the ropes and get the hang of both tools.

Keep in mind: if you use a DOSBox debug build, the built-in debug command starts the internal debugger. So if you want to be able to run DOS's DEBUG.EXE as well (or the enhanced DEBUG.COM above), you'll need to rename them.

Thanks, I'll take a look at that debugger. I'm very familiar with gdb but not debug, so I've got a bit of a learning curve ahead of me. But learning to use DOSBox's internal debugger would probably be good, maybe eventually I can track down why certain games lockup or don't work 😀. Seems like a good way to learn at least.

Thanks!

Reply 9 of 9, by llm

User metadata
Rank Member
Rank
Member

and don't forget that you can using 64bit tools to cross assemble/compile without any problems under recent Win/Linux Systems
most poeple tend to think that 16bit tools are needed for pure 16bit development - thats just not true

recent UASM 32/64 bit linux/windows (a Port if Jwasm which itself is a port of Wasm - the Watcom assembler)
under active development - very good error detection etc.
http://www.terraspace.co.uk/uasm.html

OpenWatcom V2 - Compiler, Assembler, Linker <- im using that for most of my projects
https://github.com/open-watcom/open-watcom-v2

MASM/ML
latest MASM/ML that is useable for real 16bit development is MASM/ML V9 that is integrated the VS2008 (Express) installation - fully running under Win10/Linux x64

Unilinker: super feature rich, very vibrant linker useable for any DOS/16bit action from Windows/Linux
ftp://ftp.styx.cabel.net/pub/UniLink

integrated DosBox Debugger - also very helpfull

and don't forget recent Borland 5.02/5.5 or TASM 5.x Version - also very useable for cross-development - but better use Watcom for C/C++ development