The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Brinuz on April 01, 2011, 05:19:23 PM

Title: Hello and Help Request @ Basics
Post by: Brinuz on April 01, 2011, 05:19:23 PM
Hello everyone. I'm glad i can join this community. (first post :p)

I would like to have some help tho. (Sorry for the first post here, but i guess we have to start somewhere)

Well, i learned about 16-bit ASM basics 2 years ago (was forced to...), but I can see that 16-bit ASM is pretty useless nowadays on windows. So I'm trying to re-learn everything I knew, and of course learn new things.
I faced myself with some problems, some of them i was able to solve by searching the web, this forum, etc. Others.. not really (Beginner).

So heres the problem.
I have been reading about registers (EAX,EBX,ECX,etc..) sizes and their main use, and variables (byte,word,dword).

I know a byte is 8 bits(byte), a word 16 bits(2bytes), and a dword 32bits (4bytes). And that these registers(EAX,etc..) have the total size of 4bytes (Where AX if the bottom 2bytes (or top?), which can be also divided into AL and AH, lower and higher Bytes of AX)
I'm trying to understand the basics of all this first, before anything else.

Okay i got this to print a simple string.

.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\masm32.inc
include E:\masm32\include\user32.inc

includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\masm32.lib

.data

messageStr db "Test",0
hStd dd ?
bytesOut dd ?

.code

START:

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

   

    push 0
    push offset bytesOut
    push 10
    push offset messageStr
    push hStd
    call WriteConsole
   
    push 0
    call ExitProcess

END START


Let's say I want to print the value in EDX instead of the value on the variable(byte) named messageStr.

My first thought would be:


.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\masm32.inc
include E:\masm32\include\user32.inc

includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\masm32.lib

.data

messageStr db "Test",0
hStd dd ?
bytesOut dd ?

.code

START:

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

    MOV EDX, 84 ; 'T'

    push 0
    push offset bytesOut
    push 10
    push EDX
    push hStd
    call WriteConsole
   
    push 0
    call ExitProcess

END START


But i realized fast that it wouldn't work, since edx would have stored a decimal value ("T" in ASCII), instead of the address that the WinAPI needs as parameter.
Now i ask, how would i send the address of EDX instead of the value inside? (even to print a simple character)
I tried something like: DWORD PTR EDX, but it seems to fail. (Probably for obvious reason, but since I'm way too fresh on asm... you could understand :p)

PS: Please don't tell me to use MASM macros yet. I'm really trying to avoid them at the very beginning. As i want to learn as much as I can before I use any kind of "shortcut".

Thanks in the Advance. (Please keep in mind that i also seek some theory on how this works, so i ask you to correct anything I said that could be wrong)
Title: Re: Hello and Help Request @ Basics
Post by: Tedd on April 01, 2011, 05:28:07 PM
You need to store edx somewhere (another variable) and then use the offset of that variable - the .data section is simplest.
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 01, 2011, 05:38:03 PM
Quote from: Tedd on April 01, 2011, 05:28:07 PM
You need to store edx somewhere (another variable) and then use the offset of that variable - the .data section is simplest.


Thanks for your reply, so i guess something like this would work.

.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\masm32.inc
include E:\masm32\include\user32.inc

includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\masm32.lib

.data

messageStr db "Test",0
character db ?
hStd dd ?
bytesOut dd ?

.code

START:

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

    MOV DL, 84
    MOV character, DL

    push 0
    push offset bytesOut
    push 10
    push offset character
    push hStd
    call WriteConsole
   
    push 0
    call ExitProcess

END START


I tried to save the character to the whole EDX, and realized that I couldn't reach it. Is it because it is saved on the the other 2 bytes, other that it's not DX? (DL,DH)
Title: Re: Hello and Help Request @ Basics
Post by: dedndave on April 01, 2011, 06:03:05 PM
well - you also need to convert the binary integer in EDX into an ASCII decimal string so that it makes sense
and, i understand not wanting to use the macros in the beginning - it's a good way to learn
however, for a beginner, conversion is a little bit advanced
it requires knowledge of registers, routines, and so on, that a beginner may not have yet
you can use a masm32 library function or macro to perform this operation until you get your feet wet   :bg
another good way to learn is to use the macro, but open the macros.asm file and the functions that it uses to see what they do

there are a few other things i noticed in your code that will slow you down
first, you are missing the msvcrt import library - some of the masm32 functions require it
also, you have a lot of typing at the beginning - that stuff is good to understand - not good to type
have a look at the file \masm32\include\masm32rt.inc
that file has most of the stuff you need already typed for you
so, at the beginning of the program...
        INCLUDE \masm32\include\masm32rt.inc
and that will get you going

another thing that hit me right off...
    push -11
    call GetStdHandle
    MOV hStd, EAX

it is easier to read if you...
        INVOKE  GetStdHandle,STD_OUTPUT_HANDLE
        mov     hStdOut,eax


oh - one more thing
i see that you have masm32 installed on the E: drive
the package is set up to work from the root of the current drive
so, if it is installed on E:, create your ASM files somewhere on the same drive
then use "\masm32\......."
Title: Re: Hello and Help Request @ Basics
Post by: raymond on April 02, 2011, 12:38:27 AM
QuoteI tried to save the character to the whole EDX, and realized that I couldn't reach it. Is it because it is saved on the the other 2 bytes, other that it's not DX? (DL,DH)

If you had declared the "character' variable as a dword (instead of a byte), you could then have saved the entire content of EDX in that variable.

Dave seems to have misunderstood the meaning of the value in the DL register (the ascii value of "T").
One thing you should learn is to understand the requirements of the parameters when you call one of the API functions (such as WriteConsole). If you don't have it already, get yourself a copy of the Win32 Programmer's Reference (WIN32.HLP).

The 3rd parameter for the WriteConsole function is the number of characters to be written to the console. When your test string is "Test", the passed parameter should be 4. When you store the value of DL in the "character" variable, the passed parameter should then be 1 if you want to print that single character. You should also realize that the offset of the string you pass as a parameter is strictly an address where the function will retrieve the required characters for display. It doesn't matter to the function how the data at that address was declared initially. For example,
mov edx,"tseT"
mov character,edx
and later writing 4 characters to console from the character variable would produce "Test" on the console.
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 02, 2011, 12:55:05 AM
@raymond
Let me say that I'm pretty familiar with WinAPIs that windows has.(Using them at C/C++) I know that the 3rd param would be bytes to write. I have it 10 just for testing, actually it could be easier to count the size of the string and pass it as parameter, but i really didn't mind much for this kind of testing.
MSDN pretty much says everything i need about these APIs tho.

About the DWORD, yea it makes sense indeed. Stupid of me for not remembering it. =P
Yea i realized that it was the address (pointer as msdn says) but the initial problem was just to get the address of EDX (yea prob stupid, since it isn't actually a variable)

Thanks for the input Raymond. I appreciate it.

@dedndave
Thanks about masm32rt.inc, didn't know it =]

About the invoke and push, well since i learned to use push and call at 16bits, i guess that it was what made me use it also here. Plus i used -11 on the parameter, because on MSDN the param STD_OUTPUT_HANDLE is equivalent to -11. ^^
I agree that i shouldn't include the drive on the includes list because it will be harder for others or even me to compile it somewhere else (not hard, but i would need to change these.. And it could be painful if there were many)

Thanks too for the Input, I appreciate it.

PS: Sorry for not writing perfect English, but since my natural language ain't English, i can't do it perfectly yet ^^
Title: Re: Hello and Help Request @ Basics
Post by: mineiro on April 02, 2011, 06:18:50 AM
Hello Sr Brinuz, and welcome.
.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

.data
hStd dd ?
bytesOut dd ?

.code
START:
    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

jmp that
here:
db "test",00h
here_size = $- here
that:

    push 0
    push offset bytesOut
    push here_size
    push offset here
    push hStd
    call WriteConsole
   
    push 0
    call ExitProcess

END START


with this in mind, you can write :
here:
MOV AL, "T"     ;double sense, we are searching for the "T" and puting "T" in .code section, but the sizeof is static.
here_size = $ - here
mov ecx,here_size         ;how many bytes we are search for
mov edi,offset here
repne scasb                       ;search for "AL" in offset EDI
dec edi

    push 0
    push offset bytesOut
    push 1
    push EDI
    push hStd
    call WriteConsole

Title: Re: Hello and Help Request @ Basics
Post by: dedndave on April 02, 2011, 01:39:35 PM
you can also use the stack as a temporary data area
        .XCREF
        .NOLIST
        INCLUDE    \masm32\include\masm32rt.inc
        .LIST

        .DATA?

hStdOut dd ?

        .CODE

_main   PROC

        INVOKE  GetStdHandle,STD_OUTPUT_HANDLE
        mov     hStdOut,eax

        push    eax           ;create a place on the stack for NumberOfCharsWritten
        mov     eax,esp       ;EAX = address of NumberOfCharsWritten
        mov     edx,'T'       ;EDX = ASCII 'T'
        push    edx           ;put it on the stack
        mov     ecx,esp       ;ECX = address of ASCII 'T' on stack

        INVOKE  WriteConsole,hStdOut,ecx,1,eax,0

        pop     edx           ;recall the char
        pop     ecx           ;recover NumberOfCharsWritten, balancing the stack

        INVOKE  ExitProcess,0

_main   ENDP

        END     _main
Title: Re: Hello and Help Request @ Basics
Post by: dedndave on April 02, 2011, 02:06:11 PM
the value need not be in EDX to push it
and, of course, you can output more than one character at a time
in this example, we display 'T', with a carriage return and line feed
also, the handle is still in EAX, so we use it
        push    eax             ;create a place on the stack for NumberOfCharsWritten
        mov     edx,esp         ;EDX = address of NumberOfCharsWritten
        push    'T' or 0A0D00h  ;ASCII 'T',13,10 on the stack
        mov     ecx,esp         ;ECX = address of ASCII 'T' on stack

        INVOKE  WriteConsole,eax,ecx,3,edx,0

        pop     edx             ;recall the chars
        pop     ecx             ;recover NumberOfCharsWritten, balancing the stack
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 04, 2011, 08:50:27 AM
Once again, Thanks for the useful information. Will take a deeper look into it and play around with it.
Thanks guys.
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 04, 2011, 01:52:52 PM
Erm, not sure if I can double post, but there we go.

Ok, i have been trying to Convert a number into ascii, I guess the main "problem" is solved tho. A lil bit of search and I managed to get the logic for this conversion.
(Divide by 10, get the reminder, add 48 decimal to it and there we go, I have the correct ASCII Code of the number)
Well this is not the problem.

I created a loop to check each number, save it on the stack, for later use. Thing is I'm not sure how to save it from the stack into somewhere else. Here's the code I tried:

.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\masm32.inc
include E:\masm32\include\user32.inc

includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\masm32.lib

.data
messageStr dd 1337,0
number db ?
lenght dd ?
hStd dd ?
bytesOut dd ?

.code

START:

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

    MOV ECX, 10
    MOV EAX, messageStr
    MOV EBX, 0

    convertNum:
        MOV EDX, 0
        DIV ECX
        CMP EDX, 0
        JE convertEnd
        push EDX
        INC EBX
        JMP convertNum
    convertEnd:
   
    ;This will now have the number on the stack (1,3,3,7,...)
    ;EBX will have the number lengh

    MOV lenght, EBX

    MOV EDX, offset number
    saveNumber:
        POP EAX ;recover one number from the stack to EAX and then save it
        ADD EAX, 48 ;To convert it into the correct ASCII code
        MOV BYTE PTR [EDX], EAX ;Save the number to the byte pointed by EDX
        INC EDX ;Next byte to save the next number
        DEC EBX ;Counter--
        CMP EBX, 0
        JNE saveNumber
    saveEnd:

    push 0
    push offset bytesOut
    push lenght
    push offset number
    push hStd
    call WriteConsole
   
    push 0
    call ExitProcess

END START


Well, i get an error at the line (Invalid Instruction):

MOV BYTE PTR [EDX], EAX ;Save the number to the byte pointed by EDX

But since i can't do this to save into a place in memory (variable) the value in EAX (which is one of the characters from the whole number which was in the stack)

How could I do this?

Once again, Thanks in advance, and sorry for the spelling mistakes.
Title: Re: Hello and Help Request @ Basics
Post by: dedndave on April 04, 2011, 02:03:25 PM
EAX is a dword register
you might try...
        mov     [edx],al
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 04, 2011, 02:07:35 PM
Quote from: dedndave on April 04, 2011, 02:03:25 PM
EAX is a dword register
you might try...
        mov     [edx],al

Why do i always miss the most obvious stuff. Of course. Thanks again ._.

Can't get 4Bytes into 1byte..

EDIT: And just saw another error, I'm writting to number plus the address's (EDX+1) on front of it. And these are actually being used (Handle,Lenght,BytesWritten).

Okay, here's the working "solution" that i got into

.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\masm32.inc
include E:\masm32\include\user32.inc

includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\masm32.lib

.data
messageStr dd 1337,0
hStd dd ?
bytesOut dd ?
number db ?

.code

START:

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

    MOV ECX, 10
    MOV EAX, messageStr
    MOV EBX, 0

    convertNum:
        MOV EDX, 0
        DIV ECX
        CMP EDX, 0
        JE convertEnd
        push EDX
        INC EBX
        JMP convertNum
    convertEnd:
   
    ;This will now have the number on the stack (1,3,3,7,...)
    ;EBX will have the number lengh

    MOV ECX, EBX

    MOV EDX, offset number
    saveNumber:
        POP EAX ;recover one number from the stack to EAX and then save it
        ADD EAX, 48 ;To convert it into the correct ASCII code
        MOV BYTE PTR [EDX], AL ;Save the number to the byte pointed by EDX
        INC EDX ;Next byte to save the next number
        DEC EBX ;Counter--
        CMP EBX, 0
        JNE saveNumber
    saveEnd:

    push 0
    push offset bytesOut
    push ECX
    push offset number
    push hStd
    call WriteConsole
   
    push 0
    call ExitProcess

END START
Title: Re: Hello and Help Request @ Basics
Post by: sinsi on April 04, 2011, 02:25:17 PM
You should be testing eax for zero, not edx, and you should really push edx and inc ebx before testing otherwise you will pop something that wasn't pushed (e.g. eax=0)

@@:
  sub edx,edx
  div ecx
  push edx
  inc ebx
  test eax,eax
  jz @b
@@:
  pop eax
  ...
  dec ebx
  jnz @b
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 05, 2011, 03:34:07 PM
Quote from: sinsi on April 04, 2011, 02:25:17 PM
You should be testing eax for zero, not edx, and you should really push edx and inc ebx before testing otherwise you will pop something that wasn't pushed (e.g. eax=0)

@@:
  sub edx,edx
  div ecx
  push edx
  inc ebx
  test eax,eax
  jz @b
@@:
  pop eax
  ...
  dec ebx
  jnz @b


indeed I changed it, after I realized that it wouldn't accept 0's correctly. And figured that out ^^ Thanks tho.


convertNum:
        MOV EDX, 0
        DIV ECX
        push EDX
        INC EBX
        CMP EAX, 0
        JE convertEnd
        JMP convertNum
convertEnd:


or I could use JNE there instead of these 2.. ^^
Title: Re: Hello and Help Request @ Basics
Post by: dedndave on April 05, 2011, 04:18:08 PM
probably without knowing it, you have applied Horner's Rule (or what i like to call Ling Long Kai Fang)
some time ago, i wrote a set of functions that will convert integers of any practical size to decimal string
http://www.masm32.com/board/index.php?topic=12363.msg94779#msg94779
LLKF9_1 has three procs, one for signed, one for unsigned, and one that is mode selectable
it performs base conversion on up to 9 digits at a time, then converts them to ASCII, 4 digits at a time
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 08, 2011, 11:04:32 AM
@dedndave
Yea i didn't know it =o I will give a look at your code and see what I can learn from it ^^

@

Okay after learning a bit in this topic. I decided to create one "app" that will output every friday 13th from the year 1900 to the year 2000.

I know that the code isn't nearly to perfect. But that's why I'm posting it here. In search of Tips on what to improve and why. :p

.386
.model flat, stdcall
option casemap:none

include E:\masm32\include\windows.inc
include E:\masm32\include\kernel32.inc
include E:\masm32\include\masm32.inc
include E:\masm32\include\user32.inc

includelib E:\masm32\lib\user32.lib
includelib E:\masm32\lib\kernel32.lib
includelib E:\masm32\lib\masm32.lib

GetMonthMax PROTO month:DWORD,year:DWORD

.data
hStd dd ?
bytesOut dd ?
monthsTOne dd 1,3,5,7,8,10,12,0
monthsTZero dd 4,6,9,11,0
currentDay dd ?
currentMonth dd ?
currentYear dd ?
total dd 0
number dd ?

.code

;EAX will have the days of the given month on the given year.

GetMonthMax PROC month:DWORD,year:DWORD

    MOV EDX, month

                                ;Check if it is 31 days
    MOV EBX, offset monthsTOne
    TOne:
        CMP DWORD PTR [EBX], EDX
        JE endTOne
        ADD EBX, 4
        CMP DWORD PTR [EBX], 0
        JE continueTOne
        JMP TOne
    endTOne:
        MOV EAX, 31
        JMP endProc
    continueTOne:

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

                                ;Check if it is 30 days
    MOV EBX, offset monthsTZero
    TZero:
        CMP DWORD PTR [EBX], EDX
        JE endTZero
        ADD EBX, 4
        CMP DWORD PTR [EBX], 0
        JE continueTZero
        JMP TZero
    endTZero:
        MOV EAX, 30
        JMP endProc
    continueTZero:

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

                                ;Check if it is 28/29 days

    MOV EAX, year
    MOV ECX, 4
    DIV ECX

    CMP EDX, 0                  ;Check if Year % 4 Equals 0
    JNE endTFeb28

    MOV EAX, year
    MOV ECX, 100
    DIV ECX
   
    CMP EDX, 0                  ;Check if Year % 100 Equals 0
    JNE endTFeb
   
    MOV EAX, year
    MOV ECX, 400
    DIV ECX

    CMP EDX, 0                  ;Check if Year % 400 Equals 0
    JE endTFeb28
   
    endTFeb:
        MOV EAX, 29
        JMP endProc
   
    endTFeb28:
        MOV EAX, 28
   
    endProc:
    ret
   
GetMonthMax ENDP

START:

    MOV EDX, 5                  ;Starting day of 1900 year
    MOV ECX, 1900               ;Years - Starts at 1900, Ends at 2000
    yearsLoop:
        MOV EBX, 1              ;Months - Starts at 1, Ends at 12
        monthsLoop:
            infLoop:

                CMP EDX, 13
                JNE continueInfLoop
                push EAX                ;Uses EAX as a temporary store, saving the current value of it in the stack
                MOV EAX, total 
                INC EAX
                MOV total, EAX
                POP EAX                 ;Sets EAX value back from the stack

                continueInfLoop:
                ADD EDX, 7              ;Adds 7 days to the current day
                MOV currentDay, EDX     ;saves the current day
                MOV currentMonth, ECX   ;saves the current month
                MOV currentYear, EBX    ;saves the current year

                push ECX
                push EBX
                call GetMonthMax
                MOV ECX, currentMonth   ;Restore from the variable
                MOV EBX, currentYear    ;Restore from the variable

                MOV EDX, currentDay     ;Restore from the variable
                CMP EDX, EAX
                JL infLoop
                SUB EDX, EAX
            endInfLoop:

            INC EBX                     ;Next month
            CMP EBX, 13
            JNE monthsLoop
        endMonthsLoop:
       
        INC ECX                         ;Next year
        CMP ECX, 2001
        JNE yearsLoop
    endYearsLoop:

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

    ;OUTPUT
    push -11
    call GetStdHandle
    MOV hStd, EAX

    MOV ECX, 10
    MOV EAX, total
    MOV EBX, 0

    ;Convert from Decimal to ASCII
    convertNum:
        MOV EDX, 0
        DIV ECX
        push EDX
        INC EBX
        CMP EAX, 0
        JNE convertNum
    convertEnd:

    ;Stack stores the number now in the correct order
    ;EBX will have the number lengh

    MOV ECX, EBX

    MOV EDX, offset number
    saveNumber:
        POP EAX                 ;recover one number from the stack to EAX and then save it
        ADD EAX, 48             ;To convert it into the correct ASCII code
        MOV BYTE PTR [EDX], AL  ;Save the number to the byte pointed by EDX
        INC EDX                 ;Next byte to save the next number
        DEC EBX                 ;Counter--
        CMP EBX, 0
        JNE saveNumber
    saveEnd:

    ;Write to Console
    push 0
    push offset bytesOut
    push ECX
    push offset number
    push hStd
    call WriteConsole

    ;Exit Process
    push 0
    call ExitProcess

END START


Mainly i want a tip on how to avoid the need to save every register on a variable before using them on the procedure.

                continueInfLoop:
                ADD EDX, 7              ;Adds 7 days to the current day
                MOV currentDay, EDX     ;saves the current day
                MOV currentMonth, ECX   ;saves the current month
                MOV currentYear, EBX    ;saves the current year

                push ECX
                push EBX
                call GetMonthMax
                MOV ECX, currentMonth   ;Restore from the variable
                MOV EBX, currentYear    ;Restore from the variable

                MOV EDX, currentDay     ;Restore from the variable
                CMP EDX, EAX
                JL infLoop
                SUB EDX, EAX
            endInfLoop:
Title: Re: Hello and Help Request @ Basics
Post by: dedndave on April 08, 2011, 11:40:03 AM
well - i dunno if my code is a good example   :P
whenever i post anything in here, they seem to tell me i am stupid
Title: Re: Hello and Help Request @ Basics
Post by: RuiLoureiro on April 08, 2011, 11:41:45 AM
Hi Brinuz,

replace this:
    MOV EAX, year

by this:
    xor edx, edx
    MOV EAX, year

because «div ECX» divide EDX:EAX by ECX and not only EAX by ECX !!! Ok ?
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 08, 2011, 12:07:39 PM
Quote from: dedndave on April 08, 2011, 11:40:03 AM
well - i dunno if my code is a good example   :P
whenever i post anything in here, they seem to tell me i am stupid

i'm pretty sure that for me it will be i guess? ;)

Quote from: RuiLoureiro on April 08, 2011, 11:41:45 AM
Hi Brinuz,

replace this:
    MOV EAX, year

by this:
    xor edx, edx
    MOV EAX, year

because «div ECX» divide EDX:EAX by ECX and not only EAX by ECX !!! Ok ?


I see, because of the 64 bits / 32 bits division. Thank you. Sure it is something i should do.
Title: Re: Hello and Help Request @ Basics
Post by: RuiLoureiro on April 08, 2011, 01:24:15 PM
«Mainly i want a tip on how to avoid the need to save every register on a
variable before using them on the procedure.»

Replace this:
                continueInfLoop:
                ADD EDX, 7              ;Adds 7 days to the current day
                MOV currentDay, EDX     ;saves the current day
                MOV currentMonth, ECX   ;saves the current month
                MOV currentYear, EBX    ;saves the current year

                push ECX
                push EBX
                call GetMonthMax
                MOV ECX, currentMonth   ;Restore from the variable
                MOV EBX, currentYear    ;Restore from the variable

                MOV EDX, currentDay     ;Restore from the variable
                CMP EDX, EAX
                JL infLoop
                SUB EDX, EAX
            endInfLoop:

By this:
                continueInfLoop:
                ADD EDX, 7              ;Adds 7 days to the current day
                ;MOV currentDay, EDX     ;saves the current day
                ;MOV currentMonth, ECX   ;saves the current month
                ;MOV currentYear, EBX    ;saves the current year
                push    edx
                push    ecx
                push    ebx
               
                push ECX
                push EBX
                call GetMonthMax
                ;MOV ECX, currentMonth   ;Restore from the variable
                ;MOV EBX, currentYear    ;Restore from the variable
                ;MOV EDX, currentDay     ;Restore from the variable
                pop     ebx
                pop     ecx
                pop     edx
               
                CMP EDX, EAX
                JL infLoop
                SUB EDX, EAX
            endInfLoop:


AND
replace this:
endTFeb:
        MOV EAX, 29
        JMP endProc

by this:
endTFeb:
        MOV EAX, 29
        ret
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 08, 2011, 01:27:35 PM
I was kinda afraid of doing that, because i could probably mess up with the call.
Title: Re: Hello and Help Request @ Basics
Post by: RuiLoureiro on April 08, 2011, 01:35:07 PM
OR
replace this:
GetMonthMax PROC month:DWORD,year:DWORD

by this
GetMonthMax PROC month:DWORD,year:DWORD
            push    edx
            push    ecx
            push    ebx

AND

replace this:

    endProc:
    ret   
GetMonthMax ENDP

by this:

    endProc:
    pop     ebx
    pop     ecx
    pop     edx
    ret   
GetMonthMax ENDP
Title: Re: Hello and Help Request @ Basics
Post by: Brinuz on April 08, 2011, 01:39:59 PM
Ok I understand the logic there. It could work I guess ;D

Thank you once again. Tips to improve are always welcome
Title: Re: Hello and Help Request @ Basics
Post by: RuiLoureiro on April 08, 2011, 01:52:41 PM
Quote from: Brinuz on April 08, 2011, 01:39:59 PM
Ok I understand the logic there. It could work I guess ;D

Thank you once again. Tips to improve are always welcome

Ok, using the last hint GetMonthMax doesnt destroy EDX, ECX and EBX
and we dont need to save on a variable
Title: Re: Hello and Help Request @ Basics
Post by: RuiLoureiro on April 08, 2011, 03:38:24 PM
Hi Brinuz,
             There is an error here:

.data
...
number dd ?         <<<---- here
----------------------------------

Replace this:

number dd ?

By this:

number db 20 dup (0)

Why ? number is a buffer for ascii digits