there's something that i'm unsure and would like you to clarify it for me. we all know that a PROC only exist (increase exe's size) if it's been call by CALL. otherwise, it's like a comment. for example:
for the code above, the only instruction that is being compiled is
.code start: disease proc mov ax, 2000 ret disease endp mov ax, 0 end start
. but if you have
mov ax, 0
then that procedure will be compiled as well. and you'll get the following:
what i know is that the cpu start execution downward. the question now is, how does the cpu knows not to execute instruction at:
000001FF: 00B8D007 add [007D0],bh 00000203: C3 retn 00000204: B80000 mov ax,00000 ;" " 00000207: E8F6FF call 000000200 -------- (1)
does the loader set the IP??
Code execution starts at the program's entry point (defined in the header, which is read by the os when loading the program). I'm not sure about your example but the entry point was probably set to 204, so that execution starts after the proc.
PE header contains the entry point of execution. The assembler I use has a directive entry name. If you don't use it I beleive it sets the entry point to first instruction with in code section (FAsm doesn't have procedures.) This message was edited by eet_1024, on 6/23/2001 4:36:06 PM
that's what i though, but weren't sure. thanx for the great reply tola, eet_1024
in: 00000207: E8F6FF call 000000200 -------- (1) when the processor reads "E8F6FF", it first see that "E8" is an opcode meaning for you 'call'. Then it reads the next Word, which is (in your human order: FFF6). This is a signed word meaning "-6". It pushes the adress just after (0210h) and execution jumps at "this_adress-10" (your 0200h) (remark, you disassembly is wrong because you make it start at a wrong adress -one byte too early-). This is one of the main job of what we call an Assembler, to translate what you name "disease proc", by an Adress (just a memory number) and, for calls and jumps to remplace this absolute value by a relative value, + or -, to be added or substract from actual code Pos. Now, why does it work this way, and not with the true absolute value: In case of relocation (case in which the application wouldn't be loaded at a fixed memory adress, the loader would have to re-compute all these code adresses (what we call "relocating'). With relative +/-displacement, whatever memory adress the application is loaded, it works without relocation. all this is not true for Data, which always need relocations when the upload mem adress is not virtually fixed (like it is under Win for PEs). _____________________ Now, for what MASM does or doesn't do with Procs and other things, this is simply not Assembly. This is internal Macros that drive MASM out of the Assembly area. Other true assemblers do this with user defined Macros, so that we don't have to ask what's going on, as WE have written it... betov.
disease, from the earliest 8088s to current, the capacity to use procedures was built directly into the hardware of the processor in the CALL RET/N/F instruction pair. This mechanism is supported by having an area of memory called the STACK that is usually used for passing parameters to the block of code being called. When you use "start:" in MASM you are telling the assembler where to begin execution and the corresponding "end start" tells the assembler where the program ends. The sequence of instructions that are executed are shown by the instruction pointer (EIP in 32 bit) which keeps track of what instruction will be processed next. As you would be aware, when you use the instruction CALL, it places the return address on the stack and transfers program execution to the address attached to the CALL instruction. The next occurence of RET returns the program execution to the NEXT instruction after the initial CALL instruction. With your example, the PROC is not called so it will not execute. If you really want to control a program at the lowest level, you can directly write opcodes in HEX where you have absolute control of the order but it is no joy to code a program that way, I still write DOS stubs that way when I need a custom stub but they are only 128 bytes in size generally so its no big deal to do but to code an application in that manner would be extremely slow and error prone and it would achieve no purpose. The small editor that comes with MASM32 can save opcodes written in hex to binary but it tends to only be useful when you are editing or writing an DOS header. Regards, firstname.lastname@example.org PS: Hiroshimator, as we have a couple of alternative assemblers being mentioned in the forum, would it be a good idea to give these guys a topic of their own so that people who are interested can find the stuff they are posting ?
"PROC" is just a sort of text macro, understood by this or that assembler. In MASM 32, it is part of the invoke/ proto/proc/endp formalism. In 16-bit asm settings, it is pretty well a waste of typing, especially for a routine that takes input in registers rather than on the stack. Maybe its intention is to clear up the ambiguity of the mnemonics CALL and JUMP. But in no case is it obligatory, and you can even replace it with your own macro or macros. Personally I use PROC only for 32-bit C-style routines.
Larry, yes, MASM users are alowed to not use it (great examples in Test Departement tutorials). Now, to do a Proc / EndProc with user defined Macros... in MASM, good luck... (i am ironizing, of course). betov.
Rene, Just for you, a MASM32 example of manual stack manipulation.
You will really have to learn to write in a REAL assembler before you make comments of this type. :) Regards, email@example.com This message was edited by hutch--, on 6/24/2001 8:47:28 AM
EnterStack MACRO push ebp mov ebp, esp ENDM LeaveStack MACRO mov esp, ebp pop ebp ENDM
hutch--, I believe he was talking about the full functionality of PROC/ENDP - which would be harder to realize than your little code snippet. You will really have to learn how to think a little deeper, and not assume ignorance of someone who thinks differently than you. There are some very advanced macros for NASM which have attempted to mimic all the functionality of PROC/ENDP, but I haven't seen a work around in MASM - there is no reason to. :) You can add code to the PROC/ENDP in MASM with PROLOGUE/EPILOGUE, but it lacks the power to eliminate the frame pointer (EBP) - all local varibles must be referenced from EBP. This message was edited by bitRAKE, on 6/24/2001 1:27:55 PM
Yes Ricky, i mean, of course, a full feature Proc developped by user defined Macros. Example in SpAsm: [= e < b > a =< be <= be => ae >= ae <> ne] ; Example of use: Proc CenterWindow: Arguments @Handle @Width @Hight Local @X @Y call 'User32.GetSystemMetrics' &SM_CXSCREEN If eax > D@Width sub eax D@Width | shr eax 1 | mov D@X eax Else mov D@X 0, D@Width eax End_If call 'User32.GetSystemMetrics' &SM_CYSCREEN If eax > D@Hight sub eax D@Hight | shr eax 1 | mov D@Y eax Else mov D@Y 0, D@Hight eax End_If call 'User32.MoveWindow' D@Handle D@X D@Y D@Width D@Hight &TRUE EndP Of course, to perform such a thing, and some others, the Macro system has to be very powerfull. One could say: "... and then, what difference?... the result is the same!". This is simply the difference between true Assembly and C-like Assembly. SpAsm offers the HLL level the user defines. This means that any HLL feature is rejected from the Assembler internals, and that the user is free to define the writing style he wants. This means too, that the user KNOWS what's going on because HE did it. Hutch, i'd like to insult you too, but i reserve this for private mails. Remember my first one? Still true. Kisses. betov.
betov, that would be easy to do in MASM. You assume that all local and passed parms are DWORD size - which is good for most windows stuff. MASM allows a lot more flexiblity. Yes, it seems like hutch-- and you have quite a passionate relationship. :) I do hope that I'm not getting between the two of you. :P I know it must seem that way - with you using my given name all the time. :) No one knows who your talking to. bitRAKE = Rickey This message was edited by bitRAKE, on 6/24/2001 1:49:49 PM
Where I came from, a proc is a proc, at its lowest level, a call to a label followed by a return.
If you want to use the stack to pass parameters which is a high level concept anyway, set up a stack frame with code like the 2 small macros I posted before from the MASM32 example code. If you need locals which are another high level concept, allocate the required space on the stack and start manually coding the locations from the stack in your code. Now when you are finished playing games and making a mess of doing this stuff manually, use a pre-built MASM procedure with a prototype and pick up all the other advantages of an assembler that has enough grunt to do its own type checking, allows different calling conventions and you start to get a REAL macro assembler. Assemblers that can't do this are kids toys. People who really want to write low level code write it in HEX anyway so I am yet to see the advantage of trying to sell the advantage of an assembler that is not functionally capable of at least being able to do what other high level languages can do. Differing from some of the toys around, MASM can also do many of the normal high level constructions that high level languages can do, libraries, modules that can be used by high level languages, prebuilt high level loop constructions, conditional testing and a number of other useful things. MASM can use the libraries of other Microsoft languages and this makes it considerably more powerful and flexible that languages that cannot do these things. The reason why some other assemblers have to do more in the MACRO area is because they don't have the capacity that MASM already has built into it. NASM has a very sophisticated macro system that has its own stack so that the coder can try and construct things that MASM already can do well. The main reason why simple assemblers need this type of capacity is because they are not powerful enough in the basic parsing needed to produce a decent fully developed macro assembler. Now as far as the opportunity to trade insults, you have to remember that I am an Australian and I have an engineering background before I started writing code so a very robust grasp of the idiom and a similar sense of humour is something I am very familiar with. You worry me at times Rene, I have just had part of the house rewired by one of your countrymen by the name of Jacques who was a man of considerable humour and chalm, perhaps too many years in the building game has taken the smile from your face. Bitrake, You are probably right, I reserve "thinking" for useful things like driving a nail straight, scratching myself with precision and I can even manage occasionally to do so when writing a bit of code. On another subject, I went to your site to have a look at it and for the next 15 minutes, my firewall was squarking about the amount of TCP coming from you IP, WTF is going on there ? Regards, firstname.lastname@example.org
call procname ; somewhere else in the code procname: ; your code here ret
hutch--, I don't know what your talking about? Try getting at it directly My Home, and I'd appreciate you letting me know if your get the same. It's not running from my computer, but AT&T's - I think it's the redirector and counter. You protect MASM like it was your child, or you wrote it! Come on, your arguement is just one prespective, and the fact that you preach it like it's the ONLY way demostrates your narrow little mind. The weakness of your arguement is further demostrated by your straying from the matter: argumentum ad homien, and then claiming that this is all in good humor. I can see your point and betov's without any difficulty - they both have merit! I am thankful of the time you have invested in MASM and the effort that you have put forth in the assembly community in general, but your poking at the black sheep only drives them away. When the assembly community as a whole is a black sheep, your ignorance astounds me. This message was edited by bitRAKE, on 6/24/2001 8:47:58 PM
wow! soo many post? no wonder why it's the Great PROC. :)
Rickey, cool down abit. ehehehe. you're hurting people feelings, i don't know about you, but i'm full of sympathy and empathy. This message was edited by disease_2000, on 6/25/2001 2:31:12 AM
+-----this is where disease proc begins... i though | that you guy would notice it. so i don't have | to disassembly it myself. instead, i've use | hiew to save my typing. | | betov, tha's how hiew disassembly. :) | 000001FF: 00B8D007 add [007D0],bh 00000203: C3 retn 00000204: B80000 mov ax,00000 ;" " 00000207: E8F6FF call 000000200 -------- (1)
hutch, i'm a completely different type of newbie, and i will always remain as a newbie. :) i think there's still some confusion going on here. let me make it abit clearer.
by the way, this is 16bit discussion! it has nothing to do with 32bit. if you try to compile the code above, you will not see disease proc by using a hex-editor. a procedure only exist through CALL. PROC is just a convenient thing for a programmer. Assembly is very powerful and programmers sometimes make mistake. PROC/ENDP saves us from most of the mistake that we make, or newbies(like me). now, take a look at this:
.code start: disease proc mov ax, 2000 ret disease endp mov ax, 0 <---- entry point end start
the problem with this code is that mov ax, 2000 got assembled when there's no CALL to it. LABEL that end with RET will always exist as a procedure. but with a proc beside it, it only exist through CALL. so:
.code start: disease: mov ax, 2000 ret disease endp mov ax, 0 end start
everything will compile (don't try to run it thought... cause there's no int 21h). once compiled, everything will be assembled. and the question was: HOW did the cpu knows not To execute instruction at: address 200 (that's where disease proc begins). instead, it execute instruction at address 204 (mov ax, 0). tola and eet_ clarified it for me. now, i see how it actually works. with other area that is hard for me to explain. by the way hutch, there's two instruction that can do what you've stated above. ENTER and LEAVE. i've actually never use those instruction. eheheh This message was edited by disease_2000, on 6/25/2001 2:50:48 AM
.code start: disease proc mov ax, 2000 ret disease endp mov ax, 0 call disease end start
disease, You have to look at what is happening, a processor reads instructions on a linear basis and executes them in sequence. This is a difference from what an assembler writes from code to binary. If you have ever used the old DOS debug, you will get a reasonable idea of what I am talking about.
With this code, "start:" and "disease" are labels which are address placeholders for the assembler. Your assembled code is,
.code start: disease: mov ax, 2000 ret disease endp mov ax, 0 end start
The processor will execute the instructions by following the instruction pointer (IP). To make a proc work, you have to be aware of what the IP sequence will be, (the normal downwards execution of instructions) so code must have a starting position where the instructions will begin execution. The calling of a proc must be in the normal sequence of instructions
mov ax, 2000 ret mov ax, 0
You can equally well use a label for call followed by a RET but the logic remains the same. ENTER and LEAVE used to be used by C compilers to set up the stack frame but they are too slow on modern processors and manually coding ESP/EBP usually works a lot faster. Bitrake, I will test your site again later when I get some spare time. Funny enough I have been writing assembler since you were wearing napkins and have seen many offerings in my time. I have written in a variety of assemblers and inline assemblers and see that most have their place. Like many I have outlasted the TASM push as it has died in the arse and I do see the humour of so many people attacking programmers who write in MASM as it is just a matter of fact that MASM is a lot more powerful than its competitors, Microsoft origin or not. Now my differences with Betov ar another matter, this is one area where you would be better advised to learn how to blow your nose, wash behind your ears and mind your own business. Rene is a big boy now and I am sure he does not need you to try and prop him up. This is primarily a MASM forum and while anyone is welcome to post here, it is reasonably obvious that Rene's posts are MASM hostile, including what appears to be his personal ignorance about how to write code in MASM. The last real bug I knew about in MASM was found by Iczelion and it had to do with arrays of structures, 6.13 from memory. I have no doubt that Rene comes to this forum to recruit people for his own assembler and seems to be willing to attack MASM programmers because they don't see the world his way. I am at least as cantankerous as he is and I am willing to be heard when it comes to matters of information accuracy, I can live with differences of opinion but I am not sure that Rene can. Regards, email@example.com
start: 1st_instruction ; more code call disease ; more code ; terminate process (exit to DOS) disease proc ; code here ret disease endp end start
thanx hutch, i fully understood what you're trying to say. hmm. strange that the code i posted didn't work. i though it work because it compiled perfectly.
Bitrake, I just tested the alternative URL for your site and it was no problem at all. Looks like it will be an interesting site if you ever get it finished. Regards, firstname.lastname@example.org
It is not my intension to hurt any feelings. Yes, I am young and ignorant in many matters. Yes, it's obvious that betov has problems with MASM/Microsoft, but it's also obvious to me that MASM is the tool for the job, right now. I only wish to protect the creative expression of others in the hope that MASM wont be the last great assembler. Thanks for checking on my site, I'll dump the redirector. Building the site isn't a high priority for me. It'll develope slowly, but I'll be around for another 80 years or so :D