0

I'm trying to understand assembly. Today's topic is: "Storing and incrementing int variables and printing numbers" :)

So here's my code

dane segment
     count     db     0
dane ends

code segment
start:
     inc     byte ptr ds:[count]
     inc     byte ptr ds:[count]
     inc     byte ptr ds:[count]

     mov     dl,ds:[count]
     mov     ah,2
     int     21h

     mov     ah,4ch
     int        21h
code ends
end start

When I compile and run, I got this error:

enter image description here

It only happens when count is incremented more than once. What wrong am I doing?

Can somebody explain why I can't simply write:

inc     count

Also, why I have to put byte ptr when incrementing values, but not if I copy it to dl register?

nrz
  • 10,435
  • 4
  • 39
  • 71
msmialko
  • 1,439
  • 2
  • 20
  • 35
  • I don't know about this assembly,but are you sure that aren't increment a pointer instead of value at registers? this error message seems heap corruption.. – Jack Mar 23 '13 at 17:16

2 Answers2

4

Edit: rewrote and added text, added code (works in MASM 6.11):

In x86 assembbly you need to specify the size of the memory operand for instructions in which there would be ambiguity otherwise. You have to tell the assembler the size of the operand with byte ptr, word ptr etc. For that reason inc byte ptr ds:[count] needs byte ptr. inc word ptr ds:[count is different instruction.

mov dl,ds:[count] do not need byte ptr, because dl is a 8-bit register and therefore the size of the memory operand is always the same, a byte (8 bits).

To print characters, you need to first convert the number into a string (or a single character for numbers less than 10). Otherwise you are printing control character ETX (see ASCII table) that has ASCII code 3. For numbers less than 10, printing in decimal is trivial, just add '0' (30h), like this:

mov     dl,ds:[count]
add     dl,'0'        ; add dl,30h

Printing in decimal in x86 assembly is a asked quite often, see for example Is this code correct (Number plus number, then print the result) to get the idea.

Edit: EXE files need also a stack segment.

DOS EXE files need to have a stack segment. Assembling with MASM 6.11 does not give any warnings or errors, basically with dosexe.asm (replace dosexe.asm to your assembly code file name).

But linking with ML (ml dosexe.obj) gives the following warning:

LINK : warning L4021: no stack segment

So, a stack segment needs to be added, add the following lines to top of the source.

.model small
.stack 4096

There was also some problem with data segment definition, I fixed that too.

The entire fixed assembly code could be something like this (works in MASM 6.11):

.model small
.stack 4096

.data
        count     db 0

.code
start:
        mov     ax,seg count
        mov     ds,ax

        inc     byte ptr ds:[count]
        inc     byte ptr ds:[count]
        inc     byte ptr ds:[count]

; this code does the printing in decimal without needing to reverse
; the string, by dividing the divisor. 100/10 = 10

        mov     bl,100     ; original divisor.

        mov     al,ds:[count]

print_loop:
        xor     ah,ah ; clear top 8 bits of the dividend (in ax).
        div     bl    ; divide ax by bl. quotient in al, remainder in ah.

        mov     dl,al     ; the value to be printed with ah = 2, int 21h

        mov     al,ah     ; remainder gets divided in the next loop.
        test    dl,dl     ; check if number is zero
        jz      not_print ; don't print leading zeros.

        add     dl,'0'    ; convert to ASCII numeric characters range.
                          ; '0' = 0x30 = 48
        push    ax
        mov     ah,2
        int     21h       ; print the value, according to Ralf Brown's
        pop     ax        ; interrupt list returns al.

not_print:
        push    ax
        mov     al,bl
        xor     ah,ah
        mov     bl,10     ; divide the divisor by 10.
        div     bl
        mov     bl,al     ; the new divisor.
        pop     ax
        test    bl,bl
        jnz     print_loop

        mov     ah,4ch
        int     21h
end start
Community
  • 1
  • 1
nrz
  • 10,435
  • 4
  • 39
  • 71
  • When I write "dl,ds:[count]", the same things is printed all the time - no matter what I put in count :/ Shouldn't it be just "mov dl,count"? I see this in tutorials, but I get A02074 error when I do it – msmialko Mar 23 '13 at 10:23
  • @Moriquendi What assembler you are using? You need to define the data segment, but I think the syntax for that depends on the assembler you are using. – nrz Mar 23 '13 at 10:25
  • I wish I knew that :P I've downloaded MASM compiler from my professor's website, installed Windows XP 32-bit and started to play around with sample codes. How can I check it? How others syntax may look like? – msmialko Mar 23 '13 at 10:33
  • @Moriquendi You mean other assemblers' syntax? Well, for that check some SO answers eg. with `nasm` tag. But with MASM you need to use MASM syntax, anyway. I haven't used MASM before, but anyway I fixed the bugs now and it assembles and links without problems in MASM 6.11, and prints the desired output (for any unsigned `count` value within the range 0...255). – nrz Mar 23 '13 at 19:01
0

[quote]mov dl,ds:[count] do not need byte ptr, because dl is a 8-bit register and therefore the size of the memory operand is always the same, a byte (8 bits).[/quote]

And additional this operation do not need a segment override prefix, because DS is the default segment of this operation. => mov dl,[count]

Edit:

Defines a program segment called name having segment attributes

http://msdn.microsoft.com/de-de/library/d06y3478%28v=vs.80%29.aspx

name SEGMENT [[READONLY]] [[align]] [[combine]] [[use]] [[characteristics]] ALIAS(string) [['class']]
  statements
  name ENDS

Example for using segment names:

CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
org 100h
START:
mov ax, DATEN
mov ds, ax

; your instructions

CODE ends

DATEN SEGMENT use32 'DATA'
org 0
VALUE  DD ?
DATEN ends

STAPEL SEGMENT use16 STACK 'STACK'
   DB 10h dup (0)
STAPEL ends

end

How to use segments and directives:

http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH08/CH08-3.html

...

For to link a 16 bit application using MASM 6 we need an other linker.

ftp://ftp.microsoft.com/softlib/mslfiles/lnk563.exe

Dirk