Author Topic: new user  (Read 8839 times)

nobody

  • Guest
new user
« on: March 01, 2005, 05:47:34 AM »
i'm new user in nasm and i try to write a simple coding. My aim is to add 2 number and then print out the sum..but...got syntax error...
here is the coding that i try..

org 100h

mov    ah,9            ;move the number 9 to register
add    ax,6            ;add the number 6 to same regiater
mov    sum,ax       ;move the register to the sum

int 21h

mov   ah,4ch

int 21h

sum   dh,0Dh,0Ah,'$'

what wrong with my coding?? need help and pls show me the correct coding..thanks first!!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: new user
« Reply #1 on: March 01, 2005, 08:11:57 PM »
> i'm new user in nasm and i try to write a simple coding. My aim is to add 2
> number and then print out the sum..but...got syntax error...
> here is the coding that i try..
>
> org 100h
>
> mov    ah,9            ;move the number 9 to register

Why "ah"? This looks like part of the "setup" for the "int 21h"... or is it part of the addition? In any case, ax now contains 9xxh, where the "xx" is whatever was in al at program startup. As I recall (and my memory is fuzzy on this), when a .com file starts up, ax contains the number of valid FCBs given on the command line - "probably" zero, but I wouldn't count on it. You probably want "mov ax, 9" here (assuming it's part of the addition).

> add    ax,6            ;add the number 6 to same regiater

Now al = 6 + xx... if this comes to more than 255 (unlikely in this case) there will be a carry into ah, so ah is probably still 9, but might be 0Ah...

> mov    sum,ax       ;move the register to the sum

This is the first syntax error. "sum" is the address/offset of the variable... you're trying to change an immediate value. You want "mov [sum], ax"... the "[]" indicating "contents of memory". This will overwrite the first two bytes of "[sum]" - you seem to only leave one byte in "[sum]" for the result.

> int 21h

With ah = 9, this will attempt to write a "$-terminated" string, pointed to by dx... which is "who-knows-what".

> mov   ah,4ch
>
> int 21h

Good!

> sum   dh,0Dh,0Ah,'$'

This is another syntax error. I don't know what "dl" is supposed to be... the register? I'm afraid we can't do that. If it's supposed to be a symbol, bad name... since it's a register...

What you want here (perhaps) is the $-terminated string, but with sufficient space to write the result - expressed as ascii characters, *not* just stuff the number in there!

In the simplest case, the result can be expressed as a single decimal digit...

mov al, 2
add al, 3
mov [sum], al

now "sum" looks like:

5, 0Dh, 0Ah, '$'

Printing this won't give the result you want - the number 5 is *not* the ascii character '5' - we need to add 30h or 48 or '0' to get the ascii decimal digits...

mov al, 2
add al, 3
add al, '0'
mov [sum], al

Now you'd print "5". Okay for a single digit, but if the result is 10, we need to print '1', then '0' - obviously, there's no ascii code for "10". Since ax (if that's what you want to use) will hold values from 0 to 65535, "sum" should leave space for 5 possible digits. You need to decide how large a number you want to be able to handle - the example I gave with "al" will only handle numbers from 0 to 255 - if the result is larger than 255, this simple example will silently print incorrect results! (pretty bad "bug"!) The easy fix is:

mov al, 200
add al, 60
jc overflow
add al, '0'
mov [sum], al
...

overflow:
; do something about it

If you use a 16-bit register, like ax, you can go to 65535, if you use eax, you can go to 4 billion and change - but there's *still* the possibility of an overflow, and you should still check for it!

You could also use a larger register (and/or memory location) for the "result" than for the inputs.

> what wrong with my coding??

Besides the syntax errors, you may not have thought through what you want to do...

> need help and pls show me the correct coding..

There's no single "correct" way to do it. In order to isolate the decimal digits you need to print, the "div" instruction can be useful - if you "div" by a word, the quotient is in ax, the remainder is in dx... the remainder(s) will give us the decimal digits, but in the opposite order from how we want to print them (and '0' has to be added to get an ascii character). One way to do it...

org 100h

mov ax, 9
add ax, 6
; jc overflow ; - won't happen for these inputs

mov bx, 10
mov di, sum + 4

top:
xor dx, dx
div bx
add dl, '0'
mov [di], dl
or ax, ax
jz done
dec di
jmp top
done:

mov ah, 9
mov dx, di
int 21h

; exit cleanly

sum db 0, 0, 0, 0, 0, 0Dh, 0Ah, '$'

That's untested and may have errors. Here's a slightly different way (it adds three digits, but you can figure out how to cut it down to two, I'm sure). This one *does* seem to work. It isn't intended to be the "best" method, but it's fairly easy to understand, I think.

Best,
Frank

; adds three values and prints result as decimal, hex, and binary
; nasm -f bin -o add3.com add3.asm

org 100h

section .data
    A dw 1
    B dw 2
    C dw 3
    overflow_msg db "Overflow!", 10, 13, '$'

section .text
    mov ax, [A]
    add ax,
    jc overflow
    add ax, [C]
    jc overflow

call ax2dec
    call newline
    call ax2hex
    call newline
    call ax2bin
    jmp exit

overflow:
    mov ah, 9
    mov dx, overflow_msg
    int 21h

exit:
    mov ah, 4Ch
    int 21h
;--------------

;--------------
ax2dec:
    push ax
    push bx
    push cx
    push dx

mov bx, 10          ; divide by ten
    xor cx, cx          ; zero our counter
.push_digit:
    xor dx, dx          ; clear dx for the div
    div bx              ; dx:ax/bx -> ax quotient, dx remainder
    push dx             ; save remainder
    inc cx              ; bump digit counter
    or ax, ax           ; is quotient zero?
    jnz .push_digit     ; no, do more

mov ah, 2           ; print character subfunction
.pop_digit:
    pop dx              ; get remainder back
    add dl, '0'         ; convert to ascii character
    int 21h             ; print it
    loop .pop_digit     ; cx times

pop dx
    pop cx
    pop bx
    pop ax
    ret
;-------------------

;-------------------
ax2hex:
    push cx
    push dx

mov cx, 4           ; four digits to show

.top
    rol ax, 4           ; rotate one digit into position
    mov dl, al          ; make a copy to process
    and dl, 0Fh         ; mask off a single (hex) digit
    cmp dl, 9           ; is it in the 'A' to 'F' range?
    jbe .dec_dig        ; no, skip it
    add dl, 7           ; adjust
.dec_dig:
    add dl, 30h         ; convert to character

push ax
    mov ah, 2           ; print the character
    int 21h
    pop ax

loop .top

pop dx
    pop cx
    ret
;--------------------------

;--------------------------
ax2bin:
    push cx
    push dx
    mov cx, 16
.top
    rcl ax, 1     ; rotate and set/clear carry
    mov dl, '0'
    adc dl, 0     ; make it '1' if carry set

push ax
    mov ah, 2     ; print it
    int 21h
    pop ax

loop .top

pop dx
    pop cx
    ret
;----------------------------

;----------------------------
newline:
    push ax
    push dx

mov ah, 2       ; print character in dl
    mov dl, 13      ; carriage return
    int 21h
    mov dl, 10      ; and linefeed
    int 21h

pop dx
    pop ax
    ret
;----------------------------

nobody

  • Guest
Re: new user
« Reply #2 on: March 02, 2005, 01:18:15 AM »
thanks you Frank!

nobody

  • Guest
Re: new user
« Reply #3 on: March 02, 2005, 11:15:22 AM »
After i try the coding that you show to me, when i assemble it ,stil got some error and warning..the coding i try as show below :

org 100h

section .data
A dw 1
B dw 2
C dw 3
overflow_msg db "Overflow!", 10, 13, '$'

section .text
mov ax, [A]
add ax,
jc overflow
add ax, [C]
jc overflow

call ax2dec
call newline
call ax2hex
call newline
call ax2bin
jmp exit

overflow:
mov ah, 9
mov dx, overflow_msg
int 21h

exit:
mov ah, 4Ch
int 21h
;--------------

;--------------
ax2dec:
push ax
push bx
push cx
push dx

mov bx, 10 ; divide by ten
xor cx, cx ; zero our counter
.push_digit:
xor dx, dx ; clear dx for the div
div bx ; dx:ax/bx -> ax quotient, dx remainder
push dx ; save remainder
inc cx ; bump digit counter
or ax, ax ; is quotient zero?
jnz .push_digit ; no, do more

mov ah, 2 ; print character subfunction
.pop_digit:
pop dx ; get remainder back
add dl, '0' ; convert to ascii character
int 21h ; print it
loop .pop_digit ; cx times

pop dx
pop cx
pop bx
pop ax
ret
;-------------------

;-------------------
ax2hex:
push cx
push dx

mov cx, 4 ; four digits to show

.top
rol ax, 4 ; rotate one digit into position
mov dl, al ; make a copy to process
and dl, 0Fh ; mask off a single (hex) digit
cmp dl, 9 ; is it in the 'A' to 'F' range?
jbe .dec_dig ; no, skip it
add dl, 7 ; adjust
.dec_dig:
add dl, 30h ; convert to character

push ax
mov ah, 2 ; print the character
int 21h
pop ax

loop .top

pop dx
pop cx
ret
;--------------------------

;--------------------------
ax2bin:
push cx
push dx
mov cx, 16
.top
rcl ax, 1 ; rotate and set/clear carry
mov dl, '0'
adc dl, 0 ; make it '1' if carry set

push ax
mov ah, 2 ; print it
int 21h
pop ax

loop .top

pop dx
pop cx
ret
;----------------------------

;----------------------------
newline:
push ax
push dx

mov ah, 2 ; print character in dl
mov dl, 13 ; carriage return
int 21h
mov dl, 10 ; and linefeed
int 21h

pop dx
pop ax
ret
;----------------------------


but it came out some warning and error like this :

T2.ASM:3: warning: label alone on a line without a colon might be in error
T2.ASM:9: warning: label alone on a line without a colon might be in error
T2.ASM:50: warning: label alone on a line without a colon might be in error
T2.ASM:59: warning: label alone on a line without a colon might be in error
T2.ASM:74: warning: label alone on a line without a colon might be in error
T2.ASM:79: warning: label alone on a line without a colon might be in error
T2.ASM:89: warning: label alone on a line without a colon might be in error
T2.ASM:100: warning: label alone on a line without a colon might be in error
T2.ASM:110: warning: label alone on a line without a colon might be in error
T2.ASM:110: error: symbol 'loop.top'redefined

for me..seem like no problem..but still got error...what are these warning stand for??  And how to correct it??
pls give some direction to me..thanks first!