Link to home
Start Free TrialLog in
Avatar of milalik
milalik

asked on

nietod....assembly question

this question comes as second part of Q.10318528.


This is why i wanted to see how 16 bit signed numbers work. I have no idea how to do this. I am trying to learn assembly.
1.a program that compares the elements of two arrays, A(I)and B(I). each array contains 10 16-bit signed numbers (entered from the keyboard). The comparison is to be done by comparing the corresponding elements of the two arrays until either two elements are found to be unequal or all elements are found to be equal. if the two arrays are founf to be unequal display the elements that are unequal. if both arrays are equal, display the message that both are equal.

I will appreciate your help
Avatar of snoegler
snoegler

Suppose you have array1 and array2, and each of contains already the user-entered values, and DS contains the valid descriptor to these.

push edi
push esi
mov esi,array1
mov edi,array2
mov cx,10

compare_loop:
mov ax,[esi]
mov bx,[edi]
cmp ax,bx
jnz break_loop_unequal
inc esi
inc esi
inc edi
inc edi
dec cx
jnz compare_loop

break_loop_equal:
; At this point, all elements are found
; to be equal
; ...
jmp continue

breaK_loop_unequal:
; At this point, at least one pair of
; elements are unequal.
; ...
jmp continue

; ...

continue:
pop esi
pop edi


It is unimportant for this example if the numbers you want to compare are 'signed' or 'unsigned'. If you were to multiply two signed 16-bit numbers, you had to use special mnemonics:

mov ax,32
mov bx,-483
imul ax,bx ; signed multiply
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of milalik

ASKER

nietod this is for x86 and the OS is dos.

If you can please provide the code as an example cause I am planning to use it in some other problems but I will like to see how this stuff works using code view, so I can manage to do the other problems.
thanx again
Avatar of milalik

ASKER

Another thing the comparison in the array should be like this. Lets says i have this arrays:

Array1             Array2
-10                 -8
5                    8
6                    200
8                    50
9                     .
..                     .
..                     .
..

It should compare Array1 first elemnt with array two first element. Array1 secon element with array two second element....
>> It should compare Array1 first elemnt
>> with array two first element.
It does.  That is what CMPS does.  Do you have an x86 manual or programming book?

>> If you can please provide the code as an
>> example cause
Example of what?  The comparison?  I did.  That is what the code does.  There isn't much to it.  You don't need anything else.
Avatar of milalik

ASKER

so with that code i can enter 10 digits to both arrays and compare it?
Avatar of milalik

ASKER

So how do I display the numbers that are different? And yes I have a manual...
Avatar of milalik

ASKER

What does REPZ do?
Avatar of milalik

ASKER

Adjusted points from 100 to 130
Avatar of milalik

ASKER

okay this is what I have done so far but i don't think it works like i want. I will appreciate you checked the code and fix it. thanx again.

DATA SEGMENT                
MES1 DB "PROGRAM TO COMPARE TWO ARRAYS $"      
MES2 DB "Type numbers of array: $"
MES3 DB "  is unequal to  $"
MES4 DB "The two arrays are equal $"

ARRAY1 DW 10 DUP (0)
ARRAY2 DW 10 DUP (0)
DATA ENDS

ASSUME DS:DATA,CS:CODE
START:                         
MOV AX,DATA
MOV DS,AX

MOV AH,02H ;making a return
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H

MOV AH,09H ;output a message to screen
MOV DX,OFFSET MES1
INT 21H

MOV AH,02H ; making a return
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H

MOV AH,09H ;output a message to screen
MOV DX,OFFSET MES2
INT 21H

MOV AH,02H ; making a return
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H

MOV AH,0AH ;read typed numbers
MOV SI,OFFSET ARRAY1  
MOV CX,10  
INT 21H


MOV AH,02H ; making a return
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H

MOV AH,09H ;output a message to screen
MOV DX,OFFSET MES2
INT 21H

MOV AH,02H ; making a return
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H

MOV AH,0AH;read typed numbers
MOV DI,OFFSET ARRAY2
INT 21H

REPZ CMPSW ; compare 10 words while the same.
JZ THESAME
 SUB DI,2 ; Point to element that is different.
 SUB SI,2 ; Point to element that is different
                                 ; display the elements that are different.
 JMP THEEND
THESAME:
      MOV AH,02H ; making a return
      MOV DL,0DH
      INT 21H
      MOV DL,0AH
      INT 21H

      MOV AH,09H ;output a message to screen
      MOV DX,OFFSET MES4
      INT 21H
      JMP EXIT
THEEND:

EXIT:
MOV AH,02H   ;making a return
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H

MOV AH,4CH       ;exit to DOS
INT 21H
CODE ENDS
END START
you need to set up the ES segment too so in

MOV AX,DATA
MOV DS,AX

do

MOV ES,AX

to.

In the code
MOV AH,0AH ;read typed numbers
MOV SI,OFFSET ARRAY1  
MOV CX,10  
INT 21H

you will read characters typed by the user, not the numbers they represent.  i.e. if the user enter "123" you will get the byte for an ASCII 1 followed by a the byte  for an ASFCII 2, folllowed by a byte set to ASCII for 3  You will not get a word set to 123.  okay?  You probably don't want that.  You probably want to to convert the ASCII input into binary.  As you can image that is a lot of work.  

Before you do the comparison

REPZ CMPSW ; compare 10 words while the same.
                JZ THESAME

you need to set up DI and SI to point to the start of the arrays to be compared.  Also you shoud do a CLD to make sure the direction flag is clear.  (you coudl do that at startup.)
Avatar of milalik

ASKER

so how can i minimize the work and have the program do what i want? I have no idea and i am getting frustrated.
=(
>> how can i minimize the work
The best ways would be to use C++, pascal, delphi, or basic  etc.

That is a serious answer and worth considering.  Assembly IS a lot of work.  You will be working from scratch.  It may take months to write a library of routines that do the built-in function of a modern language.  Just an ASCII to WORD procedure might take you a day to write and debug, and that is just the start of what you need.  (you need procedures for obtaining input, one for converting a WROD to ASCII, probably ones for for format input, for displaying information on the screen....)   So assembly programming is a considerable investiment, you not only are working in a low level environment, but you are starting off from scratch.  

Perhaps you should be asking yourself why you are doing this?  There are very few cases where you have to write in assembly these days.  if you are concerned with speed, you are likely to be far better off writting in a high level language and spending the time writting optimal code in the high level language rather than writing assembly from scratch.  The end result will probably be faster and will take less long to write.  If there are bottlenecks that can't be optimized enough in a high-level language, write those in assembly, you can even use in-line assembly in C++ to do this.  That is likely top be much more sensible thatn writting the whole thing in assembly.   I know.  I am the author of a 500,000 line accounting system written all in assembly.  It is FAST and powerful.  but I'm rewritting it in C++ and it will be  faster and even more powerful.  It will be faster because C++ has features that allow me to write more efficient algorithms that would not be realistic to do in assembly.
Avatar of milalik

ASKER

I have done this. What about it?
DATA SEGMENT
ARRAY1 DW 10 DUP(0)
ARRAY2 DW 10 DUP(0)
MES1 DB "BOTH ARRAYS ARE EQUAL.$"
MES2 DB "PLEASE TYPE TEN 3-DIGIT NUMBERS FOR FIRST ARRAY.$"
MES3 DB "PLEASE TYPE TEN 3-DIGIT NUMBERS FOR SECOND ARRAY.$"
MES4 DB " IS NOT EQUAL TO $"
DATA ENDS

STACK SEGMENT STACK
DB 100 DUP (?)
STACK ENDS

CODE SEGMENT
ASSUME DS:DATA, CS:CODE

START:
MOV AX,DATA
MOV DS,AX
SUB SI,SI
;-------------------------------------------------------------------------------------------------------------------
PART1:
MOV AH,02H  ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,09H  ;DISPLAY MESSAGE
MOV DX,OFFSET MES2
INT 21H

PART1A:
MOV AH,02H  ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,01H  ;WAITING FOR INPUT
INT 21H
MOV BYTE PTR[ARRAY1+1+SI],AL
MOV AH,01H  ;WAITING FOR INPUT
INT 21H
SUB AL,30H
MOV CL,4
SHL AL,CL
MOV BYTE PTR[ARRAY1+SI],AL
MOV AH,01H  ;WAITING FOR INPUT
INT 21H
SUB AL,30H
OR BYTE PTR[ARRAY1+SI],AL
ADD SI,2
CMP SI,20
JE PART2
JMP PART1A
;-------------------------------------------------------------------------------------------------------------------
PART2:  ;INITIALIZING SECOND ARRAY
SUB SI,SI
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
;-------------------------------------------------------------------------------------------------------------------
PART3:  ;MAKING OF SECOND ARRAY
MOV AH,02H  ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,09H  ;DISPLAY MESSAGE
MOV DX,OFFSET MES3
INT 21H

PART3A:
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,01H  ;WAITING FOR INPUT
INT 21H
MOV BYTE PTR[ARRAY2+1+SI],AL
MOV AH,01H  ;WAITING FOR INPUT
INT 21H
SUB AL,30H
MOV CL,4
SHL AL,CL
MOV BYTE PTR[ARRAY2+SI],AL
MOV AH,01H  ;WAITING FOR INPUT
INT 21H
SUB AL,30H
OR BYTE PTR[ARRAY2+SI],AL
ADD SI,2
CMP SI,20
JE PART4
JMP PART3A
;-------------------------------------------------------------------------------------------------------------------
PART4:
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
SUB SI,SI
SUB DI,DI
;-------------------------------------------------------------------------------------------------------------------
PART5:
MOV AL,BYTE PTR[ARRAY1+1+SI]
MOV BL,BYTE PTR[ARRAY2+1+SI]
CMP AL,BL
JE PART6
JMP PART8
;-------------------------------------------------------------------------------------------------------------------
PART6:
MOV AL,BYTE PTR[ARRAY1+SI]
MOV BL,BYTE PTR[ARRAY2+SI]
CMP AL,BL
JE PART7
JMP PART8
;-------------------------------------------------------------------------------------------------------------------
PART7:
INC DI
JMP PART10A
;-------------------------------------------------------------------------------------------------------------------
PART8:
MOV AH,02H
MOV DL,BYTE PTR[ARRAY1+1+SI]
INT 21H
MOV AL,BYTE PTR[ARRAY1+SI]
MOV CL,4
SHR AL,CL
MOV BH,AL
AND BH,0FH
ADD BH,30H
MOV AH,2
MOV DL,BH
INT 21H
MOV AH,02H
MOV AL,BYTE PTR[ARRAY1+SI]
AND AL,0FH
MOV BH,AL
AND BH,0FH
ADD BH,30H
MOV AH,2
MOV DL,BH
INT 21H
JMP PART8A
;-------------------------------------------------------------------------------------------------------------------
PART10A:
CMP DI,10
JE PART10
JMP PART9
;-------------------------------------------------------------------------------------------------------------------
PART8A:
MOV AH,09H  ;DISPLAY MESSAGE
MOV DX,OFFSET MES4
INT 21H
MOV AH,02H
MOV DL,BYTE PTR[ARRAY2+1+SI]
INT 21H
MOV AL,BYTE PTR[ARRAY2+SI]
MOV CL,4
SHR AL,CL
MOV BH,AL
AND BH,0FH
ADD BH,30H
MOV AH,2
MOV DL,BH
INT 21H
MOV AH,02H
MOV AL,BYTE PTR[ARRAY2+SI]
AND AL,0FH
MOV BH,AL
AND BH,0FH
ADD BH,30H
MOV AH,2
MOV DL,BH
INT 21H
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
JMP PART9
;-------------------------------------------------------------------------------------------------------------------
PART9:
ADD SI,2
CMP SI,20
JE PART11
JMP PART5
;-------------------------------------------------------------------------------------------------------------------
PART10:
MOV AH,09H  ;DISPLAY MESSAGE
MOV DX,OFFSET MES1
INT 21H
JMP PART11
;-------------------------------------------------------------------------------------------------------------------
PART11:
MOV AH,02H ;MAKING A RETURN
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
MOV AH,4CH  ;END OF PROGRAM
INT 21H
CODE ENDS
END START

I would seriously recommend you start using the CALL instuction!  that code is hard to follow.  it needs to be orginaized into procedures and possibly loops.  and it seriously needs comments!  Especially true in assembly.   In my accounting system I would estimate the number of comments outnumber the number of lines of code by 50%.  If I had more time, there woudl be more comments....

How about if you comment that and then mail to me at nietod@journeycom.  It is easy to deal with when its in a text editor!  (Feel free to organize first...)
Avatar of milalik

ASKER

I would try to comment it if it would do anyhelp but there are lines there I don't even know what they do. I'll think i'll give up and give you the points. I'm tired and very frustrated with all this stuff.
Here is a somewhat cleaned up version.  I've added a bunch of sub-routines.  Probably has bugs and the handling of input is at best poor, probalby is not even what you want.


DATA SEGMENT
ARRAY1 DW 10 DUP(0)
ARRAY2 DW 10 DUP(0)
MES1 DB "BOTH ARRAYS ARE EQUAL.$"
MES2 DB "PLEASE TYPE TEN 3-DIGIT NUMBERS FOR FIRST ARRAY.$"
MES3 DB "PLEASE TYPE TEN 3-DIGIT NUMBERS FOR SECOND ARRAY.$"
MES4 DB "? IS NOT EQUAL TO
SECVAL DB "?$"
DATA ENDS

STACK SEGMENT STACK
DB 100 DUP (?)
STACK ENDS

CODE SEGMENT
ASSUME DS:DATA, CS:CODE

MANPRGBGN:
              MOV           AX,DATA
              MOV           DS,AX
; need to set ES for the string instructions to work.
              MOV           ES,AX
;-------------------------------------------------------------------------------------------------------------------

              CALL          WRTRETBGN                      ; Write a return.
              MOV           DX,OFFSET MES2                 ; get -> prompt.
              CALL          DSPMSGBGN                      ; Display message.
              CALL          WRTRETBGN                      ; Write a return.
              MOV           DI,OFFSET ARRAY1               ; Get -> array to be set.
              CALL          REDARYBGN                      ; Fill in the array.

;-------------------------------------------------------------------------------------------------------------------

              CALL          WRTRETBGN                      ; Write a return.
              CALL          WRTRETBGN                      ; Write a return.
              MOV           DX,OFFSET MES3                 ; get -> prompt.
              CALL          DSPMSGBGN                      ; Display message.
              CALL          WRTRETBGN                      ; Write a return.
              MOV           DI,OFFSET ARRAY2               ; Get -> array to be set.
              CALL          REDARYBGN                      ; Fill in the array.

;-------------------------------------------------------------------------------------------------------------------

              CALL          WRTRETBGN                      ; Write a return.
              CALL          WRTRETBGN                      ; Write a return.

;-------------------------------------------------------------------------------------------------------------------

              MOV           CX,10                          ; Get number of array elements.
              NOV           SI,OFFSET ARRAY1               ; Get -> start of 1st array.
              NOV           DI,OFFSET ARRAY2               ; Get -> start of 2ns array.
              REPE          CMPSW                          ; Compare the arrays.
              JE            MANPRG010                      ; If the same branch around.
              MOV           AX,WORD PTR [SI-2]             ; Get -> 1st mismatch.
              ADD           AL,'0'                         ; Make ASCII
              MOV           MSG4,AL                        ; Update the message.
              MOV           AX,WORD PTR [DI-2]             ; Get -> 2ND mismatch.
              ADD           AL,'0'                         ; Make ASCII
              MOV           SECVAL,AL                      ; Update the message.
              MOV           DX,OFFSET MES4                 ; Get -> missmatch message
              CALL          DSPMSGBGN                      ; Display message.
              JMP           MANPRGEND

MANPRG010:    MOV           DX,OFFSET MES1                 ; Get -> match message
              CALL          DSPMSGBGN                      ; Display message.


MANPRGEND:    MOV           AH,4CH                         ;END OF PROGRAM
              INT           21H

;-------------------------------------------------------------------------------
;
;             Write a return to the display.
;
;             PRESERVES
;             All registers but AX, DX, and the flags.
;
WRTRETBGN:    MOV           DL,0DH                         ; Specify a carriage return.
              CALL          WRTCHRBGN                      ; Write the carriage return.
              MOV           DL,0AH                         ; Specify a line feed.
                                                           ; Fall into the write character function.

;-------------------------------------------------------------------------------
;
;             Write a character to the display.
;
;             PARAMETERS
;             DL - The character to be written.
;
;             PRESERVES
;             All registers but AX and the flags.
;
WRTCHRBGN:    MOV           AH,02H                         ; Specify write function.
              INT           21H                            ; Write the character.
              RET

;-------------------------------------------------------------------------------
;
;             Read a character from the display.
;
;             RETURNS
;             AL - The character that was read.
;
;             PRESERVES
;             All registers but AX and the flags.
;
REDCHRBGN:    MOV           AH,01H                         ; Specify read function.
              INT           21H                            ; Write the character.
              RET

;-------------------------------------------------------------------------------
;
;             Read a digit from the display.
;
;             RETURNS
;             AL - The ASCII value of the digit that was read.
;
;             PRESERVES
;             All registers but AX and the flags.
;
REDDIGBGN:

REDDIGTOP:    CALL          REDCHRBGN                      ; Read a character.
              CMP           AL,'0'                         ; Is character before the digits?
              JB            REDDIGTOP                      ; Yes, loop back and try again.
              CMP           AL,'9'                         ; Is character after the digits?
              JA            REDDIGTOP                      ; Yes, loop back and try again.

              RET

;-------------------------------------------------------------------------------
;
;             Display a message.
;
;             PARAMETERS
;             DS:DX - -> a message to be displayed that is terminated with a $.
;
;             PRESERVES
;             All registers but AX and the flags.
;
DSPMSGBGN:    MOV           AH,09H                         ; Specify the display message functionm.
              INT           21H                            ; Display the message.
              RET

;-------------------------------------------------------------------------------
;
;             Read an array.
;
;             PARAMETERS
;             DS:DI - 20 byte array to be read into.  The user must enter 10
;                     ASCII digits (0-1) and the binary values of the nubmers
;                     the represent will be stored into the array.
;
;             PRESERVES
;             The segment registers
;
REDARYBGN:    MOV           CX,10                          ; Number of entries to read.

REDARYTOP:    CALL          REDDIGBGN                      ; Read a digit.
              XOR           AH,AH                          ; Clear high byte of the digit.
              SUB           AX,'0'                         ; Convert ASCII to binary.
              STOSW                                        ; Store the word.
              LOOP          REDARYTOP                      ; Loop back for next entry.
              RET

              CODE          ENDS
              END           MANPRGBGN

Avatar of milalik

ASKER

I need and example of how to retrive numbers from an array
What do you mean by "retreive"

What ones do you want to get?  In what format?  Where do you want them?

How have you been trying to learn assembly?  Do you have some good books?
Avatar of milalik

ASKER

thanx for everything