1. Computer problem? Tech Support Guy is completely free -- paid for by advertisers and donations. Click here to join today! If you're new to Tech Support Guy, we highly recommend that you visit our Guide for New Members.

masm32 programming problem with matrix

Discussion in 'Software Development' started by ericlzk, Nov 7, 2007.

Thread Status:
Not open for further replies.
Advertisement
  1. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    I am having trouble understanding how the LEA instruction works on a 4x4 matrix and have try searching the net for some answers. This is my program below.
    I am trying to add the 3rd row and output it on the screen. Please help:confused:
    I have try to only output one of numbers to the screen but not successful

    ;ex5b.asm


    include c:\MASM32\work\headings2.inc
    ; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data

    xyz Dword 1, 3, -3, 7 ; A 4X4 MATRIX TABLE
    Dword 2, -5, 3, 0
    Dword 1, 7, -2, 8 ;17-28
    Dword -1, 5, 0, 6

    .code
    start: ; The CODE entry point to the program

    mov ecx,3 ; row
    mov edx,1 ; column

    abc: lea esi,[xyz-4 + ecx*4+ edx]
    mov eax,esi
    mov [xyz],eax
    ; inc edx
    ; cmp edx,4
    ; jna abc
    invoke StdOut, addr [xyz]



    exit
     
  2. johnhe

    johnhe

    Joined:
    May 11, 2007
    Messages:
    56
    It looks like you are confused about the layout of the memory used to hold the matrix and the offset of the start of the matrix rows. In assembly like in C and C++ you need to understand that arrays and matrixes are zero based but you are assuming the column is 1 based (mov edx,1 ;column). It also looks like you are assuming that each row contains 4 bytes (ecx*4) when in fact they contain 16 bytes (4 dwords).

    You also seem confused about how to move the value from the matrix into a register. The 2 instructions mov eax, si and then mov [zyz],eax copy the address of the current matrix element into xyz[0][0] overwriting the existing value with an address.

    Here is an example of how to add all of the values in the 3rd row of the matrix to get a total.

    .data

    xyz Dword 1, 3, -3, 7 ; A 4X4 MATRIX TABLE
    Dword 2, -5, 3, 0
    Dword 1, 7, -2, 8
    Dword -1, 5, 0, 6

    total Dword 0

    .code

    mov ecx,2 * 16 ; offset of 3rd row
    mov edx,0 ; column

    abc:
    ; Calc adress of next element in matrix in esi
    lea esi,[xyz + ecx + edx * 4]

    ; Copy value from this element in matrix into eax
    mov eax, [esi]

    ; Add current matrix value to the total
    add total,eax

    ; Increment the counter
    inc edx

    ; Have we passed the last column
    cmp edx, 4

    ; Keep looping if edx is less than 4
    jnae abc

    ; When we get here the value in the variable total should be 14 decimal.

    I hope this helps,
    John Hensley
    www.resqware.com
     
  3. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    Thanks alot,.. I will study it further... Please let me know how can I display it on the sceen the correct value. I am getting a melody sign
     
  4. johnhe

    johnhe

    Joined:
    May 11, 2007
    Messages:
    56
    It sounds like you might be passing the wrong type of value on the stack to the StdOut function but I can't tell because I don't any way to know what StdOut does. If you post the contents of the c:\MASM32\work\headings2.inc file that your code includes I'll take a look at the StdOut function and see if I can tell you what you need to pass to it.

    John Hensley
    www.resqware.com
     
  5. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    The file headings2.inc. The contents of the file is as below for this file.

    .486 ; create 32 bit code
    .model flat, stdcall ; 32 bit memory model
    option casemap :none ; case sensitive

    include \masm32\include\windows.inc ; always first
    include \masm32\macros\macros.asm ; MASM support macros

    ; -----------------------------------------------------------------
    ; include files that have MASM format prototypes for function calls
    ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

    ; ------------------------------------------------
    ; Library files that have definitions for function
    ; exports and tested reliable prebuilt code.
    ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    ; --------------------------------------------------------------
    ; This is a prototype for a procedure used in the demo. It tells
    ; MASM how many parameters are passed to the procedure and how
    ; big they are. This makes procedure calls far more reliable as
    ; MASM will not allow different sizes or different numbers of
    ; parameters to be passed. Note that a C calling convention
    ; procedure CAN have a variable number of arguments but these
    ; examples use the normal Windows STDCALL convention which is
    ; different.
    ; --------------------------------------------------------------

    This is a conflict between the old software my uni was using, so I had to make two files of the headings.inc

    So how I can I display the answer to the screen. I use invoke StdOut, addr [ Total]
    function and it gives me a character display.
     
  6. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    i finally found out how to display the thing , it is using the print command as below this program. Now I need to add the 4th column together and I also need to know how to add the minor diagonal for the matrix -1,7,3,7 . i am still confuse of the row and column??

    ;ex5b.asm
    include c:\MASM32\work\headings2.inc

    .data
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    xyz Dword 1, 3, -3, 7 ; A 4X4 MATRIX TABLE
    Dword 2, -5, 3, 0
    Dword 1, 7, -2, 8
    Dword -1, 5, 0, 6

    total Dword 0
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    ; This add the 4th column
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    .code
    start:
    mov ecx,0 ; first row
    mov edx,3 ; 4th column

    abc:
    lea esi,[xyz + ecx*4 + edx] ; Calc adress of next element in matrix in esi
    mov eax, [esi] ; Copy value from this element in matrix into eax
    add total,eax ; Add current matrix value to the total
    INC ECX
    INC ECX
    INC ECX
    INC ECX ; Increment the counter move to next column
    cmp ecx,12
    jnae abc
    print " The Answer is "
    print str$(total)," ",13,10

    exit
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    end start
     
  7. johnhe

    johnhe

    Joined:
    May 11, 2007
    Messages:
    56
    This example shows how to access and print out each individual element in the matrix. To access a matrix member you need to calculate the byte offset of the element and add this to matrix location in memory. This is what the lea esi,[...] instruction allows you to do. For example to access the individual element Matrix[3][2] you would use the forumla (Matrix address + (bytes per row * 3) + (Bytes per dword * 2)). The operand to the lea instruction in the sample is:

    lea esi,[MyMatrix + eax + edx * 4]

    Where eax contains (row index * BYTES_IN_ROW) and edx contains the column index effectively creating this psudeo instruction:

    lea esi,[address of MyMatrix + byte offset of row + (column * bytes in a dword)]


    .486 ; create 32 bit code
    .model flat, stdcall ; 32 bit memory model
    option casemap :none ; case sensitive

    include \masm32\include\windows.inc ; always first
    include \masm32\macros\macros.asm ; MASM support macros

    ; -----------------------------------------------------------------
    ; include files that have MASM format prototypes for function calls
    ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

    ; ------------------------------------------------
    ; Library files that have definitions for function
    ; exports and tested reliable prebuilt code.
    ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib

    MAX_ROW EQU 4 ; Number of rows in the matrix
    MAX_COL EQU 4 ; Number of columns in the matrix
    BYTES_IN_ROW EQU 4 * 4 ; 4 elements times number bytes in a dword

    .data

    MyMatrix Dword 1, 3, -3, 7 ; A 4X4 MATRIX TABLE
    Dword 2, -5, 3, 0
    Dword 1, 7, -2, 8 ;17-28
    Dword -1, 5, 0, 6

    FormatString db 'MyMatrix[%d][%d]=%d',0dh,0ah,0
    szBuffer db 256 dup(?)

    .code

    public start
    start:

    mov ecx,0 ; Index of first row

    PrintRow:
    mov edx,0 ; Index of first col

    PrintCol:
    mov eax, BYTES_IN_ROW
    mul cl ; eax = byte offset of this row in matrix
    lea esi,[MyMatrix + eax + edx * 4]
    mov eax,[esi]
    pusha
    invoke wsprintf, addr szBuffer, addr FormatString, ecx, edx, eax
    invoke StdOut, addr szBuffer
    popa
    inc edx ; Get index of next
    cmp edx,4 ; Have we passed the last column
    jnae PrintCol ; Keep looping until all columns done in this row

    inc ecx ; Get index to next matrix row
    cmp ecx, MAX_ROW
    jnae PrintRow ; Keep looping until all rows are done

    exit
    end start
     
  8. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    Thanks a lot man.. But I am confuse that u said that dword is 16 bytes when I search the internet it is saying that a dword is a 32 bit and which means 4bytes .. as a byte have 8bits ? ? ? ? . However your example program gave me an edge on how to proceed the next one on by own. thanks man..(y) Do you know if it is possible to split a BCD into a 4 bit when there is a two digit inside like this....

    abc db 00100010b ( in binary)

    basically I need to split the above array into 0010 and 0010 and add 30h to each to display it separately on the screen '22' I can display it correctly '22 on the screen if I define the array like this 00000010b,00000010b easily. I just want to know if this is possible as most books describe packed BCD but never explain how to unpacked a bcd

    Regards,,
    Eric
     
  9. johnhe

    johnhe

    Joined:
    May 11, 2007
    Messages:
    56
    I didn't mean to imply that a dword is 16 bytes. A dword is 32 bits or 4 bytes. A row in the matrix consists of 4 dwords which makes the row 16 bytes long. Since addressing in assembly is always done in byte offsets it means that to locate the start of a row in the matrix one needs to multiply the zero based row number by 16 (4 bytes per dword times 4 dwords per row).

    I don't really understand what you are trying do with the BCD stored values but unless you are only dealing with unsigned numbers there would be a lot more more than simply adding 30h to each 4 bit value because you would need to handle negative numbers.

    If you only want to access the 4 bit BCD values you can load the data from the array into a register and then shift right by 4,8,12, etc. to move the desired 4 bits into the least significant position and then mask them off by anding with 0fh.


    mov eax,[esi]
    shr eax, 24
    and eax, 0fh
    add eax, 30h

    Regards,
    John
     
  10. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    Dear John,

    Thanks for the input, I get what u mean about the help you gave... I manage to extract 4 bits of the 8bit by the and operation and mov the 4 bit data into another buffer one by one and display it. I have another problem. First this is a macro which is given on the top plus my program.

    The question is I was ask to write a program that ask user to enter two numbers decimal numbers(8 digits maximum; means 4 digits each) using the StdIn function and shows their sum on the screen.

    Basically my lecture just gave me this
    Enter Number1
    8888
    Enter Number2
    1111
    The Sum is
    9999

    how do I limit the digit and do addition and display it correctly. Do I use the function AAA?

    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    MakeToString macro lpstring ;Replaces CR (13) with 0
    local look,replace
    mov esi,0

    look: mov al,[lpstring+esi] ;get character
    cmp al,0dh ;is it CR?
    je replace ;if so go and replace it
    inc esi ;otherwise continue looking
    jmp look
    replace:
    mov [lpstring+esi],00 ;Replace CR with 0
    endm
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data?

    abc db 5 Dup(?)
    cde db 5 Dup(?)

    .code

    start:
    print "Enter Number 1:",13,10
    invoke StdIn, addr [abc],4
    mov eax,[abc]
    MakeToString eax
    print "Enter Number 2:",13,10
    invoke StdIn, addr [cde],1
    MakeToString cde
    invoke StdOut, addr [abc]


    exit

    ; « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « « «

    end start
     
  11. johnhe

    johnhe

    Joined:
    May 11, 2007
    Messages:
    56
    The easiest way to do this would be to read, validate and process 1 digit at time rather than trying to process a string. I would suggest using an algorithm such as this to avoid the need for error checking and packing/unpacking BCD numbers. This should be very straightforward to implement with masm32.

    // Prompt for first number
    DWORD Num1 = 0;
    while ( (c = getchar()) != 13 && Num1 < (MAX_DWORD/10) )
    {
    if ( c >= '0' && c <= '9' )
    {
    DWORD Digit = c -'0';
    Num1 *= 10;
    Num1 += Digit;
    }
    }

    // Prompt for second number
    DWORD Num2 = 0;
    while ( (c = getchr()) != 13 && Num2 < (MAX_DWORD/10) )
    {
    if ( c >= '0' && c <= '9' )
    {
    DWORD Digit = c - '0';
    Num2 *= 10;
    Num2 += Digit;
    }
    }

    DWORD Total = Num1 + Num2
    Output Total
     
  12. ericlzk

    ericlzk Thread Starter

    Joined:
    Nov 7, 2007
    Messages:
    8
    is this the same as masm32... I could not put this in masm32 to run it.
     
  13. johnhe

    johnhe

    Joined:
    May 11, 2007
    Messages:
    56
    No, it is pseudo code just to give you an example of the algorithm. I was trying to give you an idea of how to generate a binary number from user input. Here is some masm32 code that shows how to get generate a binary number from keyboard input. It's basically an implementation of the first while loop from the pseudo code above.

    .486 ; create 32 bit code
    .model flat, stdcall ; 32 bit memory model
    option casemap :none ; case sensitive

    include \masm32\include\windows.inc ; always first
    include \masm32\macros\macros.asm ; MASM support macros

    ; -----------------------------------------------------------------
    ; include files that have MASM format prototypes for function calls
    ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\msvcrt.inc


    ; ------------------------------------------------
    ; Library files that have definitions for function
    ; exports and tested reliable prebuilt code.
    ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\msvcrt.lib

    .data

    RequestFirstNumber db 'Enter the first 4 digit number',0dh,0ah,0
    RequestSecondNumber db 'Enter the second 4 digit number',0dh,0ah,0
    CrLf db 0dh,0ah,0

    Number Dword 0
    Digit DWORD 0

    .code

    public start
    start:

    ; Prompt user for first number
    invoke StdOut, addr RequestFirstNumber


    ; Number of digits to get in loop
    mov ecx,4

    Get4Digits: ; Start of loop to get 4 digits

    ; Get next character from keyboard
    pusha
    invoke crt__getch
    mov Digit, eax
    popa

    ; Check for enter key to end input
    cmp Digit, 13
    je HaveNumber

    ; Only allow valid digits
    cmp Digit, 30h
    jb Get4Digits
    cmp Digit, 39h
    ja Get4Digits

    ; Display the valid digit
    pusha
    push Digit
    invoke crt_putchar
    add esp,4
    popa

    ; Convert digit to binary
    sub Digit,30h

    mov eax,Number
    mov edx, 10
    mul edx
    add eax, Digit
    mov Number,eax
    loop Get4Digits

    HaveNumber:

    invoke StdOut, addr CrLf
    invoke StdOut, addr RequestSecondNumber

    exit
    end start
     
  14. Sponsor

As Seen On
As Seen On...

Welcome to Tech Support Guy!

Are you looking for the solution to your computer problem? Join our site today to ask your question. This site is completely free -- paid for by advertisers and donations.

If you're not already familiar with forums, watch our Welcome Guide to get started.

Join over 733,556 other people just like you!

Loading...
Thread Status:
Not open for further replies.

Short URL to this thread: https://techguy.org/648888