Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

80x86 assembly

Options
  • 22-04-2002 10:55am
    #1
    Registered Users Posts: 18,484 ✭✭✭✭


    Has anyone got a good site or two with a few pointers for 8086 asm newbies? I'm having major difficulties writing a simple program that lets the user input 5 integers, adds them, displays the total, then displays them in ascending order, and then calculates the average (integer though, don't care about the bit after the decimal point).

    well?

    *bangs head off wall repeatedly*


Comments

  • Registered Users Posts: 2,199 ✭✭✭Keeks


    Post up what code you have and i might be able to help.

    I take this is something for college, and that you have the input/output routines from your notes already?


  • Registered Users Posts: 18,484 ✭✭✭✭Stephen


    Yeah its something for college. I've been provided with the I/O routines, but i'll throw them in here for you to see:
    ioprocs.asm:
    title ioprocs.asm
    
    .model small
    
    BDOS    EQU 21h
    CR      EQU 0dh
    LF      EQU 0ah
    
    .stack 100h
    .data
    .code
    
    public INDEC, OUTDEC, NEWLINE
    
    INDEC   PROC    NEAR    ;INPUT PROCEDURE
            PUSH    BX      ;SAVE REGISTERS
            PUSH    CX
            PUSH    DX
            XOR     BX,BX   ;CLEAR N
    INDEC0: PUSH    BX      ;SAVE N
            CALL    GETC    ;GET NEXT CHARACTER
            POP     BX      ;RESTORE N
            CMP     AL,'0'  ;< 0?
            JB      INDEC2  ;YES
            CMP     AL,'9'  ;> 9?
            JA      INDEC2  ;YES
            SUB     AL,'0'  ;GET DECIMAL DIGIT
    INDEC1: PUSH    AX      ;SAVE DIGIT
            MOV     AX,10   ;MULTIPLY N BY 10
            MUL     BX
            MOV     BX,AX
            POP     AX      ;RESTORE DIGIT
            XOR     AH,AH
            ADD     BX,AX   ;ADD IN DIGIT
            JMP     INDEC0  ;GET NEXT DIGIT
    INDEC2: MOV     AX,BX   ;RETURN N IN AX
            POP     DX      ;RESTORE REGISTERS
            POP     CX
            POP     BX
            RET
    INDEC   ENDP
    
    
    OUTDEC  PROC            ;OUTPUT PROCEDURE
            PUSH    AX      ;SAVE REGISTERS
            PUSH    BX
            PUSH    CX
            PUSH    DX
            XOR     CL,CL   ;INITIALISE DIGIT COUNT
            MOV     BX,10   ;SET UP DIVISOR
    OUTD1:  XOR     DX,DX   ;ZERO HIGH ORDER WORD OF DIVIDEND
            DIV     BX      ;DIVIDE BY 10
            PUSH    DX      ;SAVE REMAINDER ON STACK
            INC     CL      ;BUMP COUNT
            CMP     AX,0    ;ANYTHING LEFT?
            JA      OUTD1   ;YES, GET NEXT DIGIT
            XOR     CH,CH   ;ZERO HIGH ORDER BYTE OF COUNT
                            ;FOR LOOP
    OUTD2:  POP     AX      ;GET A DIGIT FROM STACK
            ADD     AL,'0'  ;GET CHARACTER CODE FROM DIGIT
            PUSH    CX      ;SAVE CX
            CALL    PUTC    ;OUTPUT THE DIGIT
            POP     CX      ;GET CX BACK
            LOOP    OUTD2   ;LOOP TILL CL=0
            POP     DX      ;RESTORE REGISTERS
            POP     CX
            POP     BX
            POP     AX
            RET             ;RETURN TO CALLER
    OUTDEC  ENDP
    
    
    NEWLINE PROC    NEAR    ;NEWLINE OUTPUT PROCEDURE
            PUSH    AX      ;SAVE REGISTERS
            PUSH    BX
            PUSH    CX
            PUSH    DX
            MOV     AL,CR   ;GET CR CHARACTER
            CALL    PUTC    ;OUTPUT
            MOV     AL,LF   ;GET LF CHARACTER
            CALL    PUTC    ;OUTPUT
            POP     DX      ;RESTORE REGISTERS
            POP     CX
            POP     BX
            POP     AX
            RET             ;RETURN TO CALLER
    NEWLINE ENDP
    
    
    PUTC    PROC    NEAR    ;CHARACTER OUTPUT PROCEDURE
            PUSH    AX      ;SAVE REGISTERS
            PUSH    BX
            PUSH    CX
            PUSH    DX
            MOV     DL,AL
            MOV     AH,02H  ;CALL OS FUNCTION 2
            INT     BDOS
            POP     DX      ;RESTORE REGISTERS
            POP     CX
            POP     BX
            POP     AX
            RET             ;RETURN TO CALLER
    PUTC    ENDP
    
    
    GETC    PROC    NEAR    ;CHARACTER INPUT PROCEDURE
            PUSH    BX      ;SAVE REGISTERS
            PUSH    CX
            PUSH    DX
            MOV     DL,AL
            MOV     AH,01H  ;CALL OS FUNCTION 1
            INT     BDOS
            POP     DX      ;RESTORE REGISTERS
            POP     CX
            POP     BX
            RET             ;RETURN TO CALLER
    GETC    ENDP
    
    
    end
    


    And here's my smelly work in progress effort - as you can see it requires lots more work:
    .model small
    .stack 100h
    .data
    ;        in_char db      1
    InPrompt1      	DB      'Enter number 1:','$'
    InPrompt2      	DB      'Enter number 2:','$'
    InPrompt3      	DB      'Enter number 3:','$'
    InPrompt4      	DB      'Enter number 4:','$'
    InPrompt5      	DB      'Enter number 5:','$'
    PutRslt	       	DB      'Result is:', '$'
    Total	       	DW      	0
    number1		DW	0
    number2		DW	0
    number3		DW	0
    number4		DW	0
    number5		DW	0
    
    .code
    
    	extrn	outdec:		proc
    	extrn	indec:		proc
    	extrn	newline:	proc
    
            mov     ax,@data
            mov     ds,ax
    
    	mov	ah,9
            mov     dx,OFFSET InPrompt1
            int     21h
    	call	indec
    	mov     bx,ax
    	call	newline
    	mov	ah,9
    	mov	dx,OFFSET PutRslt
    	int 	21h
    	mov	ax,bx
    	call	outdec	
    	mov	ah,4ch
    	int	21h
    end
    

    Man I really prefer Java :)


  • Registered Users Posts: 2,281 ✭✭✭DeadBankClerk


    we learned moterolla 68k assembly last year...


    man 80x86 looks nothing like it :)


  • Users Awaiting Email Confirmation Posts: 3,129 ✭✭✭Samson


    I hate nmemonics.

    I could never get my head 'round that assembler sh!te.
    Thank God programming (of any description) was only a small portion of my course.

    I have a couple of old assembly language books on a shelf here somewhere if anyone wants them.


  • Registered Users Posts: 18,484 ✭✭✭✭Stephen


    As it is now, my crappy little program reads in 5 integers from the user, adds them up, displays the result, then calculates the average (integer part only) and displays that. I'm fooked if I can figure out how to sort the numbers in ascending order.


  • Advertisement
  • Registered Users Posts: 2,199 ✭✭✭Keeks


    try implementing a bubble sort....i did up one years ago but i don't have access to any of those files at the moment


  • Closed Accounts Posts: 1,567 ✭✭✭Martyr


    You could do it like this, i know its a little crude, but it works.
    It doesn't print a number entered more than once though in ascending order.I had a few ways of doing it, but this is the easiest way i could think of doing it even though its not very good.I'd be interested in seeing the full working solution from either you or your teacher.please post it when you can.
    thanks.
    you can get the *.asm file here http://homepage.eircom.net/~geek/hw.asm
    start hw.asm
    ; tasm ioprocs.asm ; school routines
    ; tlib ioprocs.lib +ioprocs.obj
    ; tasm /zn /z hw.asm
    ; tlink /x hw,,,ioprocs.lib
    ;
    model small

    stack 64h

    dataseg

    szCRLF db 13, 10, 0
    szMsg db 13, 10, "Numbers from 1-255 only", 0
    szPrompt db 13, 10, "Enter number ", 0
    szEnter db 13, 10, "Numbers entered: ", 0
    szTotal db 13, 10, "Total value of numbers entered: ", 0
    szAverage db 13, 10, "Average for total: ", 0
    szOrder db 13, 10, "Numbers in ascending order: ", 0

    lpNumbers dw 5 dup (0)
    lpOrdered db 256 dup (0)

    codeseg

    extrn outdec :proc ; external school routines
    extrn indec :proc

    public printf
    public newline ; internal routines
    public putchar

    main:
    mov ax, @data
    mov ds, ax
    mov es, ax
    ;##########################################################################
    mov di, offset lpOrdered
    add di, 256 ; advance di to last byte in buffer lpOrdered
    mov al, "!" ; ! is our end marker
    mov byte ptr [di], al ; save at last byte in buffer
    mov di, offset szMsg
    call printf
    xor si, si ; zero si
    inc si
    GetInput:
    mov di, offset szPrompt ; our input prompt
    call printf ; print it
    mov ax, si
    call outdec
    mov dl, ":"
    call putchar
    call indec
    or ax, ax ; zero input?
    jz GetInput ; if yes, then start again
    cmp ax, 00ffh ; check if more than 255?
    jg GetInput ; if greater jump back to prompt
    dec si ; else decrement counter
    mov word ptr [lpNumbers + si], ax ; save, si indicates current byte position
    inc si
    mov bx, ax
    mov byte ptr [lpOrdered + bx], al ; save byte
    cmp si, 0005h ; fifth round?
    je DisplayEntered ; if equal, we're finished
    inc si ; increment counter
    jmp GetInPut ; keep going

    DisplayEntered:
    call newline
    mov di, offset szEnter
    call printf

    mov si, offset lpNumbers
    xor ax, ax
    xor bx, bx
    AddTotal:
    mov al, byte ptr [si]
    inc si
    or al, al
    jz DisplayTotal
    add bx, ax
    call outdec
    mov dl, " "
    call putchar
    jmp AddTotal

    DisplayTotal:
    call newline
    mov di, offset szTotal
    call printf

    mov ax, bx
    push ax
    call outdec
    call newline
    DisplayAverage:
    mov di, offset szAverage
    call printf
    pop ax
    xor dx, dx
    mov cx, 0005h ; divide count
    div cx ; divide ax by 5
    call outdec
    call newline

    DisplaySorted:
    mov di, offset szOrder
    call printf
    mov si, offset lpOrdered
    xor ax, ax
    Looper:
    mov al, byte ptr [si]
    inc si
    cmp al, "!"
    je Exit
    cmp al, 00h
    je Looper
    call outdec
    mov dl, " "
    call putchar
    jmp Looper

    Exit:
    call newline
    mov ah, 4ch ; MS-DOS exit()
    int 21h
    ;###################################################################################
    PutChar proc
    push ax
    mov ah, 02h ; MS-DOS putc()
    int 21h
    pop ax
    ret
    endp

    newline proc
    mov di, offset szCRLF
    call printf
    ret
    endp

    printf proc
    push bx ; save some registers on the stack
    push cx
    push ax
    mov dx, di ; address dx with di/string to print
    stc ; set carry flag
    sbb cx, cx ; subtract with borrow cx = -1/FFFFh maximum search depth
    xor ax, ax ; scan for null/zero
    repnz scasb ; repeat scan until byte@di = zero or cx = zero
    not cx ; negate cx for total bytes scanned+null
    dec cx ; shave off last byte coz its zero
    mov ah, 40h ; MS-DOS output to device
    xor bx, bx ; zero bx
    inc bx ; incrememt for Standard Output
    int 21h
    pop ax
    pop cx
    pop bx
    ret ; return to caller
    endp

    end main

    end hw.asm


  • Closed Accounts Posts: 375 ✭✭Baldy


    .model small

    .stack 100h

    .data
    Numbermsg DB 'Please enter number ','$'
    col DB ': ','$'
    TheTotal DB 'The total is: ','$'
    AverageMsg DB 'The integer average is: ','$'

    i dw 6
    j dw 0
    temp dw 0
    counter dw 1
    numarray dw 0,1,2,3,4
    total dw 0
    position dw 0
    smallst dw 101
    Divisor dw 5

    .code
    extrn outdec : proc
    extrn newline : proc
    extrn indec : proc

    mov ax,@data
    mov ds,ax
    mov cx,5
    mov si,0
    indata: mov dx,offset numbermsg
    mov ah,9
    int 21h
    mov ax,counter
    call outdec
    mov dx,offset col
    mov ah,9
    int 21h
    call indec
    add total,ax
    mov numarray[si],ax
    add si,2
    inc counter
    call newline
    loop indata

    mov si,0
    mov cx,5
    next: mov ax,numarray[si]
    call newline
    call outdec
    add si,2
    loop next

    call newline
    mov dx,offset TheTotal
    mov ah,9
    int 21h
    mov ax,total
    call outdec

    call newline
    mov dx,offset AverageMsg
    mov ah,9
    int 21h

    mov ax,total
    mov bx,Divisor
    mov dx,0
    div bx
    call outdec
    mov ax,0

    call newline

    mov si,8
    ****************************************************
    loop1:
    mov bx,si
    mov i,bx

    cmp i,1
    jae loop2

    cmp i,1
    jb ender

    loop2:
    dec i
    mov j,1
    mov bx,j

    cmp bx,i
    jbe doif

    dec j

    cmp bx,i
    ja loop1

    doif:

    dec j
    mov bx,numarray[si-2]
    mov temp,bx

    mov bx,numarray[si]
    mov numarray[si+2],bx

    mov bx,temp
    mov numarray[si],bx
    call outdec

    jmp loop2
    ****************************************************

    ender:

    mov si,0
    mov cx,5
    next2: mov ax,numarray[si]
    call newline
    call outdec
    add si,2
    loop next2

    mov ah,4cH
    int 21h

    end

    ____________________________________________________

    between the stars I am caught in an infinite loop for this bubble sort algorithm, My head cant figure out whats going on plz help lads :(

    clocked up 18 hours on this program over the last 3 day :( i think im gonna cry! help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help help :(


  • Closed Accounts Posts: 1,567 ✭✭✭Martyr


    ; Get 5 numbers from the user.
    ;	Display entered, total, average, in ascending order.
    ;
    model	small
    
    dataseg
    
    lpArray		db	6	dup	(0)
    
    szPrompt		db	13, 10, "Enter number ", "$"
    szEntered		db	13, 10, "Numbers entered: ", "$"
    szTotal		db	13, 10, "Total: ", "$"
    szAverage		db	13, 10, "Average: ", "$"
    szOrder		db	13, 10, "Ascending order: ", "$"
    
    codeseg
    
    extrn		indec		:proc
    extrn		outdec	:proc
    
    main:
    	mov	ax, @data
    	mov	ds, ax
    	;--------------
    	mov	bx, offset lpArray
    	xor	si, si
    	xor	di, di
    	inc	si
    GetInput:
    	mov	dx, offset szPrompt
    	call	printf
    	mov	ax, si
    	call	outdec
    	mov	dl, ":"
    	call	putc
    	call	indec
    	or	al, al
    	jz	GetInput
    	mov	byte ptr [bx + di], al
    	inc	di
    	inc	si
    	cmp	di, 0005h
    	jne	GetInput
    	mov	dx, offset szEntered
    	call	printf
    	mov	si, offset lpArray
    	xor	bx, bx
    AddTotal:
    	xor	ax, ax
    	lodsb
    	or	al, al
    	jz	DisplayTotal
    	add	bx, ax
    	call	outdec
    	mov	dl, " "
    	call	putc
    	jmp	short AddTotal
    DisplayTotal:
    	mov	dx, offset szTotal
    	call	printf
    	
    	xchg	ax, bx
    	push	ax
    	call	outdec
    DisplayAverage:
    	mov	dx, offset szAverage
    	call	printf
    	
    	pop	ax
    	xor	dx, dx
    	mov	cx, 0005h
    	div	cx
    	call	outdec
    DisplaySorted:
    	mov	dx, offset szOrder
    	call	printf
    ;-------------------------------------------
    SortBytes:
    	mov	si, offset lpArray
    	xor	ax, ax
    SortLoop:
    	lodsb
    	cmp	byte ptr [si], ah
    	je	EndSort
    	cmp	byte ptr [si], al
    	jnb	SortLoop
    	xchg	byte ptr [si], al
    	xchg	byte ptr [si - 1], al
    	jmp	short SortBytes
    EndSort:
    	mov	si, offset lpArray
    ;--------------------------------------------
    PrintRest:
    	xor	ax, ax
    PrintBytes:
    	lodsb						
    	or	al, al				
    	jz	Exit					
    	call	outdec				
    	mov	dl, " "
    	call	putc
    	xor	ax, ax		
    	jmp	short PrintBytes		
    Exit:
    	mov	ah, 4ch			
    	xor	al, al			
    	int	21h				
    ;---------------------------------------------------
    printf	proc
    	mov	ah, 09h
    	int	21h
    	ret
    endp
    
    putc	proc
    	mov	ah, 02h
    	int	21h
    	ret
    endp
     
    end	main
    


  • Registered Users Posts: 18,484 ✭✭✭✭Stephen


    I'll post the solution as soon as I get it from the lecturer :)


  • Advertisement
  • Closed Accounts Posts: 375 ✭✭Baldy


    no offence m8 but if i used it id get a big fat 0 cause 95% of that code is over my head


  • Closed Accounts Posts: 1,719 ✭✭✭Ruaidhri


    ok here is my solution.complete with comments
    what do you tink?


    ; Author:Ruairi Carroll (CNW1009)
    ; Date:26th April 2002
    ; Title:Aveorder.asm
    ; Function:This prog takes 5 numbers from the user
    ; and sorts then using bubble sort.
    ; outputs the average and the numbers in acsending oders

    .model small
    .stack 100h
    .data
    GetNum DB 'Please Enter Number ','$'
    AveMsg DB 'The Average Of Those 5 Numbers Is: ','$'
    Sorted DB 'The Sorted Array is (in assending order): ','$'
    GetNumCount DW 1
    Colon DB ':','$'
    getindex DB 1
    TOTAL DB 0
    array db 5 dup (?)
    ArraySize dw $-array ;ArraySize=no of elements
    .code
    extrn indec: proc
    extrn outdec: proc
    extrn newline: proc

    mov ax,@data ;move data to data segment
    mov ds,ax

    mov cx,5 ;setup first loop to go around 5 times
    mov si,0 ;set si(used here to index the array) to 0
    Getnumber: mov dx,offset GETNUM ;setup GETNUM for output
    mov ah,9
    int 21h
    mov ax,GetNumCount ;this is to "count" the number of times the user has been asked for numbers
    call outdec
    inc getnumcount ;increment GetNumCount for next execution of the loop
    mov dx,OFFSET colon
    mov ah,9
    int 21h
    call indec
    mov ah,0 ;Zero the higher order bits in ax,because the array is using 8 bit numbers,al is needed only
    mov array[si],al ;put current value from user into the current slot in the array
    inc si ;increment the array pointer.since 8 bit numbers are being stored in the array we only need to increment si by one,if it was 16-bit then we would have in increment by 2
    call newline
    Loop Getnumber ;jump to the label Getnumber 5 times

    jmp bubsort ;jump the the sorting code(in this case it's Bubble Sort)

    CONT: mov cx,5 ;labelled CONTinue to jump back from from the bubble sort code
    mov si,0 ;setting up next loop

    GetTotal: mov ah,0 ;zero the high order bits in ax
    mov al,array[si] ;move the current element in the array into the lower order bits in ax
    add total,al ;add al to the TOTAL.this is because you cant directly add to values in a memory location together
    inc si
    LOOP GetTotal

    mov Dx,OFFSET AveMsg ;output the message to say what the averag is
    mov ah,9
    int 21h ;INTerrupt 21H , function 9

    mov al,total ;setup the total value of digits to be outputted
    mov ah,0 ;zero high orde bits so ax=contents of al only
    mov dx,0 ;Set Dx to zero..important to do before division
    div ArraySize ;Divide contents of ax(AL) by the total number of elements in the array
    mov bh,ah ;backup ah to bh
    mov bl,al ;same for al
    mov ah,0 ;zero the high order bits of ax,so after divisino all there is left is the Quotient
    call outdec ;output Quotient
    call newline

    mov Dx,OFFSET sorted ;output message to say array is sorted
    mov ah,9
    int 21h
    call newline

    mov cx,5 ;setup next loop to go around 5 times
    mov si,0 ;zero the register to address the array
    numout: mov al,array[si] ;move current element to al
    mov ah,0 ;Zero the high order bits in AX so AL only will be outputted
    call outdec
    call newline
    inc si
    loop numout ;loop numout 5 times

    mov ah,4ch
    int 21h ;Exit: INTerrupt 21H,Function 4CH

    BubSort:mov bx,ArraySize ;"bubbles"larger elements to "top" of array and smaller elements to "Bottom" of array
    dec bx ;bx=no of passes needed to complete sorting(n-1)

    outloop:mov cx,bx ;cx=no of comparisions to be performed in a pass
    mov si,0

    Inloop: mov al,array[si] ;setup current element for comparison
    inc si ;move to next element in the array
    cmp al,array[si] ;CoMPare previous element to current element in the array
    jb NoSwap ;if previous element is below then jump to NoSwap
    xchg al,array[si] ;eXCHanGe al with current element(so previous and current element's positions can be swapped
    mov array[si-1],al

    NoSwap: loop inloop ;loop INnerLOOP until cx is zero
    dec bx ;take 1 from bx(which wil be transferred to CX,thus acting as a loop counter
    jnz outloop ;Jump on Not Zero to outloop
    jmp cont ;Jump back to CONTinue above
    END


  • Closed Accounts Posts: 1,567 ✭✭✭Martyr


    Yeah Ruaidhri, I like the sorting part, the smaller the better.
    I dunno why I used the xlat instruction which is why I changed the routine a little that day after I realised it wasn't needed, now it sorts in descending and ascending order depending on value in cx.
    Baldy, no offence taken,maybe if you run the program in Turbo Debugger you will understand how it works a bit better?


  • Closed Accounts Posts: 375 ✭✭Baldy


    its grand i got the thing work about ten mnutes after i posted that nevermind m8 soz :)


Advertisement