VOGONS


First post, by DieJay

User metadata
Rank Newbie
Rank
Newbie

Hi everyone!

I wanted to do some classic DOS programming in assembly but since I'm stuck with Windows 7, I can't run TASM, TLINK or TD. Thanks to DosBox though, I could run them again without having to switch OSes or PCs.

However, I noticed something weird; if I define the program model as TINY, it makes the DIV and MUL operators crash the program. So in a nutshell, somehow, having the same segment for the code and data screws up the multiplication and division operators when running the program in DosBox (it runs just fine on the real thing). I don't get it.

Does anyone knows what may be causing this?

Here's an example program to show you what I mean.

.MODEL SMALL
; ".MODEL TINY" will make the program crash somewhere between line 21 and 30.
.STACK 256
.8086

.DATA
labelStart DB "Program started.", 10, 13, '$'
labelDivision DB "A division was made.", 10, 13, '$'
someWord DW 03C8h

.CODE
main PROC
mov ax, @data
mov ds, ax

; display "Program started."
mov ax, 0900h
lea dx, labelStart
int 21h

; test simple division
mov ah, 0
mov al, BYTE PTR [someWord]
mov bx, 2
div bx

; display "A division was made."
mov ax, 0900h
lea dx, labelDivision
int 21h

; wait for a key
mov ah, 07h
int 21h

; end program with code 0
mov ah, 04Ch
mov al, 0
int 21h

main ENDP
END main

Edit: Yeah, I realize this is a pretty far fetched issue, but I'd be curious if the topic has been brought up before or, god forbid, there's an actual reason why this is happening.

Reply 1 of 2, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

The program is stuck on an unhandled divide overflow exception because you're not caring for what is in DX. Maybe these other systems where you say it "runs just fine" have default divide error handlers or something causing different exception handling behavior, but ultimately you've made a programming mistake.

In executable memory models DX is zero because your initial message string has an offset of zero in the data segment. In tiny memory model DX is not zero because the data segment is the same as the code segment and the string offset is somewhere after the code.

You should zero DX because you're doing an unsigned divide; with a signed divide (IDIV) you'd probably want a CWD to extend the sign from AX into DX.

     ; display "Program started."
mov ax, 0900h
lea dx, labelStart
int 21h

; test simple division
mov ah, 0
mov al, BYTE PTR [someWord]
+ xor dx, dx
mov bx, 2
div bx

Reply 2 of 2, by DieJay

User metadata
Rank Newbie
Rank
Newbie

Well I'll be damned... I had completely forgotten that the DIV operator used the register dx:ax! No wonder it was buggy.

Sorry for making such a newbie mistake, I'm actually new to assembly. And thanks for the heads up, I'll make sure to double check my code next time ^^;