▄▄             ▄▄▄  ▄▄▄ Power
█  █ ▄▄▄▄ ▄▄▄▄▄ █  █ █  █
█▄▄█ █▄▄▄ █ █ █ █▀▀▄ █▀▀▄
█  █ ▄▄▄█ █ █ █ █▄▄▀ █▄▄▀

Login
Register
/ aa about.it ad amd64 and.who api asm asmbb asmbb.features authentication bbcode best bugs bulma cares chat common debian decentralization deck design dll docker email embed fast feature files fossil fresh.ide friendly gamedev heap help hiawatha high.cpu i18n ideas incredible interop learning libfresh limit links linux mailing.list meme meta.http-equiv minimag money mysql neo nginx numbers orly os outage pass password post-by-email programmers programming proile read-by-email resources safety script.alert.xss secret seo skins sodom source sourcecode stress.test subdirectory subforum suggestion support tags templates test test123 theme type very.ugly video work xss игнат котики парола русский тест уеб.програмиране хабр.наполеон
Categories Threads

Error detected RSS

0 1 2

Error detected in Fresh\freshlib\sqlite\sqlite.asm, line# 30: unbalanced stack

KyberMax

Error detected in Fresh\freshlib\sqlite\sglite.asm, line# 30: unbalanced stack

I totally forgot about it and used a modified procedure, for example in the project AsmBB. But now it is fixed in the branch FreshLibDev.

johnfound

I totally forgot about it and used a modified procedure... it is fixed in the branch FreshLibDev.

OK, got it. I just downloaded your Fresh IDE package to look at the sources (it is absolutely impossible to use it without a warm tube dark theme). I just opened some files and saw this error.

I must say that the cause of the error is your slightly dangerous style with multiple exits from the procedures, because the flat assembler does not automate the work with the stack as HL compilers or MASM. IMHO, even with MASM, is better not to do this (because it can become a bad habit).

KyberMax

I must say that the cause of the error is your slightly dangerous style with multiple exits from the procedures, because the flat assembler does not automate the work with the stack as HL compilers or MASM. IMHO, even with MASM, is better not to do this (because it can become a bad habit).

Well, yes, it is dangerous somehow. But once fixed, there is no problem anymore. rofl

Also, similar problems are actually pretty obvious and easy for fixing...

johnfound

Well, yes, it is dangerous somehow. But once fixed, there is no problem anymore. rofl Also, similar problems are actually pretty obvious and easy for fixing...

Well, I agree that it is obvious that these errors are obvious, but experience seems to hint to us that they are possible and therefore IMHO is better to completely eliminate them, slightly correcting the style than catching them all over the code (usually there are enough problems without this type mistakes, is not it?).

KyberMax
johnfound

Well, yes, it is dangerous somehow. But once fixed, there is no problem anymore. rofl Also, similar problems are actually pretty obvious and easy for fixing...

Well, I agree that it is obvious that these errors are obvious, but experience seems to hint to us that they are possible and therefore IMHO is better to completely eliminate them, slightly correcting the style than catching them all over the code (usually there are enough problems without this type mistakes, is not it?).

If you are talking about the multiple returns from the procedures, it IMHO actually increases the code readability. The alternative is a multiple jumps and branches that can easily turn the code into a spaghetti pot... But it is always some kind of trade-off between readability, speed, size and bug-proof.

Another possible way is to automate the way registers are stored/restored by the procedure macros. But, personally for me, this way in fact elevates the level of the language - something I am trying to avoid. Turning this way, you will end with a wanna-be-high-level macro library, limiting the user the same way, high level languages do. If I wanted this, I would program in C/C++.

And if you ask where is the borderline between lo/high level - it is personal. For me, the current set of the freshlib code generation macros is the maximal level I think is reasonable. (The data definition macros are totally different story.)

johnfound

If you are talking about the multiple returns from the procedures, it IMHO actually increases the code readability. The alternative is a multiple jumps and branches that can easily turn the code into a spaghetti pot... But it is always some kind of trade-off between readability, speed, size and bug-proof.

Well, I'm talking about multiple returns, of course, because the cause of the error was precisely inattention during one of the manual stack restorations before returning. I agree about readability, but is it worth sacrificing security for them? However, you decide, of course.

By the way, there is a way to avoid multiple jumping to the exit or error (MASM):

Example PROC PUSH error INVOKE Proc1 JNC cont1 RETN ; Error cont1: INVOKE Proc2 JNC cont2 RETN ; Error cont2: ..... ok: POP EAX ; Popping error address JMP exit error: ..... exit: ..... RET ; Only one return from procedure Example ENDP
johnfound

Another possible way is to automate the way registers are stored/restored by the procedure macros. But, personally for me, this way in fact elevates the level of the language - something I am trying to avoid. Turning this way, you will end with a wanna-be-high-level macro library, limiting the user the same way, high level languages do. If I wanted this, I would program in C/C++.

I also hate to tolerate the excess of macros - the tube warm of the Assembler is lost.

KyberMax

I agree about readability, but is it worth sacrificing security for them?

Hm, I don't think one can sacrifice security for readability at all. Actually, in long term, the readable code is always more secure.

The discussed bug is not actually good example, because this procedure was never used in real code. I am using it for opening SQLite database in AsmBB, but I simply copied the code in the project from another project. Because simply forgot that the same procedure was included in FreshLib.

First of all, it would be necessary to clarify that security here is a characteristic of the programming style, i.e. this style helps to avoid coding errors or helps to make them happen. Another characteristic of the style is the readability of the code.

johnfound

Actually, in long term, the readable code is always more secure.

Not always, and this case is a good example. Indeed, multiple returns from procedures have good readability, but in combination with manual stack work, this style:

Firstly, promotes to making errors (each time the number and/or the order of the registers stored in the stack change, it is necessary to make edits in several places in the code).

Secondly, can hide an error due to the occasional execution of some returns (as in the case under consideration).

johnfound

The discussed bug is not actually good example

It is obvious that this error is a issue of the programming style in which your source are created. Sad but true.

Today I downloaded and looked at the fasm source. Well, my impression of it is that fasm programmers are orphans, because no one thinks about their safe programming style.

And only MASM programmers are elite because dear and beloved Micro$oft has long thought about their safe programming style and did enough for that. He solved the problem of register saving elegantly by embedding it in the PROC directive:

Example PROC Uses ESI EDI EBX ; The Uses option enables saving these registers to the prolog ..... ..... RET ; This directive forms the epilogue and the restore registers from the stack Example ENDP

It may be possible for fasm programmers to at least try to achieve the unattainable ideal of divine MASM by modifying already existing macros designed to form a prologue and an epilogue. The begin macro can take saved registers as arguments and include it in the prolog. Accordingly, the return macro should include their restore in the epilogue.

Something like that:

proc Example begin esi edi ebx ..... ..... return ..... ..... return ..... return endp

instead of this:

proc Example begin push esi edi ebx ..... ..... .wrong_register_order: pop ebx esi edi ; FAIL. Most likely even EPIC return ..... ..... .wrong_register: pop ebx edi eax ; FAIL. Most likely also EPIC return ..... ..... .extra_register: pop ebx edi esi eax ; EPIC FAIL return ..... ..... .ifnrequent_ret_with_missing_register: ; shit will happen when a lot copies will be spread pop ebx edi ; EPIC FAIL return endp

The great humanist old cook hutch in his kangaroo pen took a programmer with such style by the legs and killed him against the wall.

KyberMax

And only MASM programmers are elite because dear and beloved Micro$oft has long thought about their safe programming style and did enough for that. He solved the problem of register saving elegantly by embedding it in the PROC directive:

This is not a matter of "poverty". It is a realized trade-off because of the better control! As I already said, if you really want the compiler to control your code for "safety", use high level languages.

There was many experiments with FASM macro system in the past. Including development of almost "high-level" languages with full control of the stack, calls, etc. All of them failed, because the safety gain is not enough to justify the lost of control.

In fact, as I already said, more control means more safety in long-term aspect, even if it causes more bugs in short-term period. And this is good IMHO.

johnfound

This is not a matter of "poverty". It is a realized trade-off because of the better control!

What are you talking about? In the above quotation there is no word taken by you in quotes.

If you are talking about MASM, then the "trade-off" is simple: it only frees the programmer from the routine and dangerous fuss with the stack. In the fasm, this is also partially implemented as a macro begin return push pop. The problem is that it is partially.

johnfound

...the safety gain is not enough to justify the lost of control.

Great, and now answer the simple question: what is the use of manually restoring registers before each return? Why do you need this "control" in this particular case?

johnfound

In fact, as I already said, more control means more safety in long-term aspect, even if it causes more bugs in short-term period. And this is good IMHO.

It's all just a theory, but in practice you created a monstrously ridiculous and dangerous style, where you dazzled in a heap multiple returns, safe only when automating stack work, and manual work with this stack. Although this work is easily automated. As a result, you got an ideal machine gun for shooting your own leg.

KyberMax

Great, and now answer the simple question: what is the use of manually restoring registers before each return? Why do you need this "control" in this particular case?

I can decide to pop not all registers from the stack, because of some reason. Or pop them in different order, if I want to return their values exchanged. Or to push/pop different group of registers, depending on the program flow.

Here is an example:

proc ItIsBetter, .Arg1, .Arg2, .Arg3, .Arg4 begin push eax mov eax, [.Arg1] cmp eax, 42 jne .exit1 push ecx mov ecx, [.Arg4] jecxz .exit2 push esi edi mov esi, [.Arg2] mov edi, [.Arg3] rep movsd pop edi esi .exit2: pop ecx .exit1: pop eax return endp
KyberMax

It's all just a theory, but in practice you created a monstrously ridiculous and dangerous style, where you dazzled in a heap multiple returns, safe only when automating stack work, and manual work with this stack. Although this work is easily automated. As a result, you got an ideal machine gun for shooting your own leg.

But strange none of my legs is shot. My projects written in this style are not too buggy (and the revealed bugs are diagnosed and fixed easily) and the programs work in a field better than similar programs written in HLL. It's a magic! Isn't it? rofl

johnfound

I can decide to pop not all registers from the stack, because of some reason. Or pop them in different order, if I want to return their values exchanged. Or to push/pop different group of registers, depending on the program flow.

Here is an example

It is clear that you can do anything, it is not clear just for what. In a huge number of cases, this freedom is absolutely unnecessary. But you always pay a high price for this unnecessary freedom.

The example you give is a rare exception, where you are apparently trying to reduce the execution time. It is possible that I, too, in this case would not follow the standard style, however I would do it a little differently: I would pass the parameters through the register-pointer to the structure, not through the stack, and would not load the data into the registers for analysis.

Something like this:

PBIN TYPEDEF Ptr ; COND_MOV_MEM STRUC cond Dword ? pDst PBIN ? pSrc PBIN ? lMem Dword ? COND_MOV_MEM ENDS ; .CODE ItIsTheBest PROC ; Input: EBX = pointer to struct ; MASM not create stack frame if no args & local vars ; Proc.just for local labels ASSUME EBX: Ptr COND_MOV_MEM CMP [EBX].cond, 42 JNE exit CMP [EBX].lMem, 0 JE exit PUSH ECX PUSH EDI PUSH ESI MOV ECX, [EBX].lMem MOV EDI, [EBX].pDst MOV ESI, [EBX].pSrc REP MOVSD POP ESI POP EDI POP ECX ASSUME EBX: Nothing exit: RET ItIsTheBest ENDP
johnfound

But strange none of my legs is shot.

Well, here you can just look at the first post of this topic.

johnfound

My projects written in this style are not too buggy...

I did not say that your code is buggy, I just said that your style is dangerous, i.e. requiring greater attention to a large number of dangerous little things, which increases the likelihood of errors, reduces the speed of code creation and increases the complexity of maintenance.

johnfound

...(and the revealed bugs are diagnosed and fixed easily) and the programs work in a field better than similar programs written in HLL. It's a magic! Isn't it?

Actually, no, because I also write on asm, my code also works well, and following the safe coding style allows me not to use the debugger.

Error detected in \Fresh\freshlib\FreshEdit\FreshEdit.asm, line# 500: unbalanced stack (return w/o pop esi)

KyberMax

Error detected in \Fresh\freshlib\FreshEdit\FreshEdit.asm, line# 500: unbalanced stack (return w/o pop esi)

Yes, there is. But I will not fix it. The TFreshEdit component is actually not working, not finished and in the same time obsolete and superseded by TAsmEdit ( freshlib/gui/TAsmEdit.asm ) which uses TText ( freshlib/data/buffergap.asm ) as a text storage structures and has much higher performance.

And as a whole, the GUI part of FreshLibDev branch (that is currently merged into Fresh IDE) is also not finished and generally will be superseded soon.

The current development process of the GUI part of FreshLib (the directories gui/ and graphics/) is performed into the branch NoCanvasGUI.

So, if you want to help to the process of GUI components development, please, examine the branch NoCanvasGUI. There are definitely bugs that need to be fixed.

johnfound

...I will not fix it. The TFreshEdit component is actually not working, not finished and in the same time obsolete...

Well, actually I found two more:

Error detected in \Fresh\freshlib\FreshEdit\FreshEdit.asm, line# 657: wrong register pop order

Error detected in \Fresh\freshlib\FreshEdit\FreshEdit.asm, line# 1019: unbalanced stack (pop eax w/o push)

I place them here only so that you pay attention to the type of these errors and take seriously the writing by me about your programming style.

johnfound

...if you want to help to the process of GUI components development...

I did not find these errors on purpose (however, like the first error in this thread). I just looked through your development and saw them by chance. If I look at the branch you have proposed, then only for obvious errors, you know why.

It is interesting that such an obvious thing had to be explained for almost a week. Obviously this is due to the poor English of Google translator, through which I write like Kraftwerk sings through the synthesizer. I know English poorly (in the future everyone will speak Russian only) but even I was funny from some Google translations. For example, "старинный знакомый" is not translated as "old cock" IMHO. But whether Google knows something about the great Australian humanist, or whether SkyNet trolls cyborg through Google - who knows?

Well, the mechanism of the first machine gun for shooting in the your leg is now obvious and its dismantling is also obvious and for the most part already described above. You can modify the prologue and epilogue (begin and return macros) as described above. If this is impossible or difficult, then it is necessary to reduce multiple returns to one in all procedures.

But the best way is to use both methods not only to eliminate the effect of accidental programmer errors, but also to ensure that the executable code is not clogged with numerous epilogues and does not look like HLL shit.

However, there is another machine gun, which is impossible not to see looking at your source. This, of course, using the stack top to temporarily save registers. This is a very common and dangerous method, and its danger increases in proportion to the distance between push and pop.

This machine gun is dangerous seeming ease of use and even easier to get an epic fail in the form of a shot through the leg. The cause of this is obvious: push/pop method requires increased attention and does not forgive errors. For example, it is very easy to get an unbalanced stack, just forgetting to pop the register out of the top stack.

You swing this machine gun right and left, watering all around in your source code by the push/pop bullets like Terminator, and you may already have shot your leg more than once without even noticing it. But it is even easier to shoot your leg just in the process of maintaining the code.

Fixing the problem is obvious as the problem itself: use local variables instead of register saving commands at the stack top. Of course, this is a more complex method than push/pop, but it is safe and also improves the readability of the code if you use informative names of local variables.

So, paraphrasing an expression from the excellent film "The Diamond Hand", we can summarize: "take care of your leg, Vanya".

KyberMax

I know English poorly (in the future everyone will speak Russian)

Давай тогда лучше на великим и могучим. Зачем мучить бедного гугл переводчика?

0 1 2
Categories Threads

Error detected RSS

AsmBB v2.7 (check-in: b1b34acbf71dada0); SQLite v3.29.0 (check-in: fc82b73eaac8b369);

©2016..2018 John Found; Licensed under EUPL.
Powered by Assembly language
Created with Fresh IDE

Icons are made by Egor Rumyantsev, vaadin and icomoon from www.flaticon.com