News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

new member introduction and advice

Started by q12, September 04, 2021, 12:42:56 PM

Previous topic - Next topic

q12

Hello Vortex
I tested your console code and also download it from the attachment (which I was not familiar in the very begining).
I keep getting a black console window poping out when I execute the file. This happens only in C:/ drive. In D:/ drive it is not appearing, but also the compiler is not making anything in this last drive. Works Only in C:/
I think I understand your pages that you linked, for the OFFSET keyword you used in the code and also for the MB_OK.
The Iczelion's tutorials are looking very interesting !
I will start them. Most probably by simply copy their code to get used with things.
{
I'll have to make the effort of writing my own programs, dealing with simple stuff like aritmetic operators and booleans for the momment
It was in plan, until the new tutorials arrived from you. But it is very good !
New tutorials are always welcomed ! The best thing I can do, is to copy things, haha.
}

Hello six_L
Very memorable face... , also very nice x64dbg software. I download it, and unzip it and run it.
I run a very simple console program from those demo in masm32 folder. Just to test it and it works.
I love it's user interface with all it's colorfull and good taste icons in it!!!
But... is still over my head. I did come across such debuggers in my life so I am somewhat familiar with their existence.
But im not pertinent to say I can use them.
Thank you, I put it aside for future use, when I will be more sure how to use it.

At Vortex again:
Thank you very much for the complete explanation on these general registers !
It REALLY helped me understand them more clearly now.
Also you give me a nice hint for what are good for, the Push(save) and Pop(load) opcodes.
Now we understand eachother!!! Keep explaining like this and we are lift off sooner than expected.

to caballero:
Im doing my best!  ...and it is slow and hard.
Im not rushed to go anywhere so im doing it at my normal pace.

Thank you all!

Vortex

Hi q12,

You are welcome. The message box example is not console application, it's a GUI sample.

A loop sample ( console application ) and preserving the value of ebx :

include \masm32\include\masm32rt.inc

.data

s1          db 'This is the first loop example',13,10,0
s2          db 'This is the second loop sample',13,10,0

.code

start:

    call    myproc
    call    sample
   
    invoke  ExitProcess,0

myproc PROC uses ebx

; The uses statement will take care of ebx

    mov     ebx,3

loop1:

    invoke  StdOut,ADDR s1
    dec     ebx
    jnz     loop1

    ret

myproc ENDP


sample PROC

    push    ebx
    mov     ebx,4

mylabel:

    invoke  StdOut,ADDR s2
    dec     ebx
    jnz     mylabel

    pop     ebx
    ret

sample ENDP

END start




avcaballero

Hi, q12, here's a starting point that you may find useful... or not, who knows  :greensml:

http://abreojosensamblador.epizy.com/?Tarea=6&SubTarea=2&Lang=1

mineiro


include \masm32\include\masm32rt.inc
;perceive call/ret pairs
;perceive push/pop pairs
.code
start:
    call trash_registers        ;save manually registers contents
    call trash_registers2       ;uses masm automation
    mov eax,0
    call dont_trash_eax
    invoke  ExitProcess,EAX     ;exit this process returning 0 (eax) as OK information
   
trash_registers proc
    push ebx        ;save register contents in stack
    push edi        ;do this at start of your procedure/function/routine
    push esi

    mov ebx,0       ;trash registers contents
    mov edi,1
    mov esi,2

    pop esi         ;restore them before ret or exit, note, reverse order
    pop edi
    pop ebx
    ret             ;return one instruction after who called us
trash_registers endp

trash_registers2 proc uses ebx edi esi          ;"uses" will save (push) and restore (pop) as example above
    mov ebx,0       ;trash registers contents
    mov edi,1
    mov esi,2
    ret             ;return one instruction after who called us
trash_registers2 endp

dont_trash_eax proc uses eax                    ;"uses" will save and restore only eax
    mov eax,2           ;trash eax
    ret
dont_trash_eax endp

END start           ;our code begins at "start" label
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

q12

Quote from: Vortex on September 10, 2021, 06:41:52 AM
You are welcome. The message box example is not console application, it's a GUI sample.
You really don't trust my word.
The windows form (messagebox) is opening fine in both drives, c:\ and d:\
But that Big Black Console window !
Here is what it does while run from c:\ drive. It does not appear when it is run from d:\ drive.
That black console window should not appear at all, indiferent of the drives it is run ! It is what Im saying.
I am unsure if this is normal, that it should suppose to happen or not.
But, its a little detail that is really non important.


jj2007

In case you are using qEditor: there is "Build all" and "Console build all". Check the difference.

hutch--

 :biggrin:

I think I understand you now.
So only these 3: EAX ECX and EDX are OK to use.
EBX ESI and EDI to protect them as you put it. So not to touch.
ESP and EBP to not touch them ever.
Correct?

No, you are AGAIN making unsound assumptions.

EBX ESI and EDI to protect them as you put it. So not to touch.

You use EBX, ESI and EDI on a needs basis using the PUSH POP pair. Much later you can use EBP and ESP once you understand what they do.

You get your ear chewed because you MUST GET THIS RIGHT, make incorrect assumptions now and it will be a lot harder to fix it later.

q12

to mister hutch
I clarified the general registers already with mister Vortex (after talking with you)
Here is how I saved the last clarification:

EAX ECX and EDX     OK to use at will. They are volatile registers meaning, their value is destroyed across Windows API calls.
EBX ESI EDI and EBP Need protection, they can be modified with the condition that you preserve their original values before exiting a procedure. They are non-volatile registers.
                    "You save (push at the beginning) and restore (pop accordingly) them, before returning to the caller." -
ESP                 should not be modified as it's responsibility is to address the stack frame

q12

I started to write some code myself, looking and not looking at the samples codes.
I made a couple of test-code that speedup my understanding of these basic opcodes and sintax.
I concentrated on: mov, add and sub opcodes
LOCAL var1  :DWORD    from 1 sample code did helped me understand the mechanism a bit more faster.
I watched some video tutorials and they helped me speed up understanding.
So
I jumped to mul operand and I understand now how is working. And I have no problems with it's code.
I jumped to div operand and I understand now how is working. But I have a problem with it's code!!! A windows error appear when it tries to execute the div statement.
I've made some basic test-codes for each operand I am using. Mostly to get used to it and with the assembler syntax.
Check attachment of this message, for the div code. Remember, I did it as a test code. That's why is looking like an experimental code.
Here is the windows error that I get only from div operator:


hutch--

You keep modifying the advice you are given, EBP (the base pointer) is used in conjunction with ESP (that stack pointer) to provide the stack frame for normal procedures. Try using EBP in a normal procedure and it will most probably CRASH on you. Stick to the normal 3, EAX ECX & EDX and with protecting the non volatile registers, ESI EDI & EBX.

Do it the right way and you will write reliable code, do it any other way and get used to unreliable crashes. You can write a massive amount of code with the 6 available registers, it is only specialised code with no stack frame that does otherwise.

mineiro

build as console


include \masm32\include\masm32rt.inc

.data
var5 dd 1 ;INITIALIZED data, GLOBAL scope, all code can play with this

.data?
var6 dd ? ;UNITIALIZED data, GLOBAL scope, all code can play with this
;we need initialize this variable in our code before use this

.code
start:
call main
exit


main proc uses ebx esi edi
LOCAL var1:DWORD ;UNITIALIZED data, LOCAL scope, can be played only inside this proc
;each time we run a program this variable will have different values
;so we need first initialize this variable
LOCAL var2:DWORD
LOCAL quotient:DWORD
LOCAL remainder:DWORD

mov var1,9 ;initializing these local variables
mov var2,2

print chr$("dividend = ")
print str$(var1)
print chr$(13,10)

print chr$("divisor = ")
print str$(var2)
print chr$(13,10)

mov edx,0 ;edx:eax pair in mul/div instructions
;edx value at this point can be anything, so lets zero it
mov eax, var1 ;0:9
mov ecx, var2 ;09 / 2 = ?
div ecx             ;divide edx:eax by ecx and store quotient in eax and remainder in edx
   
;eax,edx,ecx are volatile registers, so, if I like to print their contents, the next
;time that I will print again values in these registers will probably get destroyed
;so I need save them before print
   
mov quotient,eax
mov remainder,edx
   
print chr$("quotient = ") ;this print probably destroyed some volatile registers
print str$(quotient) ;but we saved before that contents in some variables
print chr$(13,10) ;print CR LF (Carriage return, Line feed)
   
print chr$("remainder = ")
print str$(remainder)
print chr$(13,10)

ret
main endp

end start
I'd rather be this ambulant metamorphosis than to have that old opinion about everything

TouEnMasm


The div operation need an edx NULL if it is a dword operation ( other way edx:eax = QWORD)
Quote
Divides unsigned the value in the AX, DX:AX, EDX:EAX, or RDX:RAX registers (dividend) by the source operand
   (divisor) and stores the result in the AX (AH:AL), DX:AX, EDX:EAX, or RDX:RAX registers. The source operand can
   be a general-purpose register or a memory location. The action of this instruction depends on the operand size
   (dividend/divisor). Division using 64-bit operand is available only in 64-bit mode.
   Non-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magni-
   tude. Overflow is indicated with the #DE (divide error) exception rather than with the CF flag.
   In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to addi-
   tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is
   applied, the instruction divides the unsigned value in RDX:RAX by the source operand and stores the quotient in
   RAX, the remainder in RDX.
   See the summary chart at the beginning of this section for encoding data and limits. See Table 3-15.
   Table 3-15. DIV Action
   Maximum
   Operand Size                         Dividend          Divisor         Quotient            Remainder             Quotient
   Word/byte                            AX                r/m8            AL                  AH                    255
   Doubleword/word                      DX:AX             r/m16           AX                  DX                    65,535
   Quadword/doubleword                  EDX:EAX           r/m32           EAX                 EDX                   232 - 1
   Doublequadword/                      RDX:RAX           r/m64           RAX                 RDX                   264 - 1
   quadword
Fa is a musical note to play with CL

q12

Mister mineiro, just perfect code, my hat off.
Fantastic working code and most of all, explanations per each line. Just brilliant !
I wish every tutorial to be like you just created here with your code and comments.

q12


q12

Can anyone make an educated guess what the correspondent in masm32 will be for this:
"f              Register file address (0x00 to 0x7F)"
It's very important for me to nail this thing. For me it looks like a variable (var1) or another register (like EBX).
But I want to be sure, by asking you.
Please see the image table I made here: https://i.imgur.com/2AqsZe1.jpg
or check the attachment for the same image file.