1

I wrote the procedure PRINTNR which divides sequentially the number in AX by 10, saves the rest on the stack. After the number in AX register becomes 0, I sequentially extract the digits from the stack, and add 30h in order to obtain the ascii code of the respective digit. Then I call the 02h function with INT 21h. When I assemble it, it freezes my DosBox.

CODE SEGMENT PARA 'CODE'
ASSUME CS: CODE

MAINPROC PROC FAR
    PUSH DS
    XOR AX, AX
    PUSH AX

    
    MOV AX, 5
    CALL PRINTNR
    
    RET
MAINPROC ENDP

PRINTNR PROC NEAR
    ;IN AX WE HAVE THE NUMBER
    MOV CX, 0
    MOV BX, 10
AGAIN:
    INC CX
    DIV BX
    PUSH DX
    MOV DX, 0
    CMP AX, 0
    JNE AGAIN

LOOPPRINT:
    POP DX
    ADD DL, 30h
    MOV AH, 02h
    INT 21h
    LOOP LOOPPRINT
    
    RET
PRINTNR ENDP

CODE ENDS   
END MAINPROC

Can you find out what's the problem?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Kudor
  • 17
  • 3
  • 3
    You have unbalanced `push ds`/`push ax` right at the start for whatever reason. That will cause the `ret` to break, even if all your other code is correct (which I have not yet checked). Also for your `div bx` to work you should zero `dx` before the first iteration as well (just move the `mov dx, 0` to before the `div`). – Jester May 11 '22 at 11:10
  • Use a debugger to single-step your code and find out exactly where it crashes. Also, you need to zero DX *before* the first `div`, not just for subsequent ones, unless your function requires the caller to pass a value in `DX:AX` which can be up to `(10 * 2^16) - 1`. But you said the input is only in AX, so DX could hold garbage. See [Displaying numbers with DOS](https://stackoverflow.com/q/45904075) for working code. – Peter Cordes May 11 '22 at 11:13
  • Also, it freezes DOSBox when you *assemble* it, without even running it? I assume you meant it freezes when run. – Peter Cordes May 11 '22 at 11:14
  • Yes, it froze when I RAN it, not when I assembled it. I put a MOV DX, 0 at the start of the procedure and it worked, ty!!! – Kudor May 11 '22 at 11:24
  • @Kudor Assemblers won't give you a compile error if your code doesn't properly balance the stack. I'd recommend indenting everything between a `push` and a `pop`, as if those instructions were curly braces in C. – puppydrum64 Dec 22 '22 at 15:28
  • Also it seems in your code you have a `push dx` inside your `again` loop with just a single `pop` outside, this will also imbalance your stack. If you really need an unbalanced `push` inside the loop you can use another variable to track how many times you've looped, then outside the loop, either create a second loop that pops that many times, or add that value to `sp` twice. – puppydrum64 Dec 22 '22 at 15:32

0 Answers0