AsmBB

Power
Login Register

Error detected
0

0 1 2
#15823 (ツ) KyberMax
Last edited: 22.04.2019 by KyberMax, read: 5045 times

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

#15824 (ツ) johnfound
Created 22.04.2019, read: 5043 times
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.

#15825 (ツ) KyberMax
Last edited: 22.04.2019 by KyberMax, read: 5035 times
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.

#15826 (ツ) KyberMax
Created 22.04.2019, read: 5032 times

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).

#15827 (ツ) johnfound
Created 22.04.2019, read: 5030 times
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...

#15828 (ツ) KyberMax
Created 22.04.2019, read: 5028 times
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?).

#15829 (ツ) johnfound
Created 22.04.2019, read: 5025 times
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.)

#15830 (ツ) KyberMax
Created 22.04.2019, read: 5022 times
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.

#15831 (ツ) johnfound
Created 23.04.2019, read: 5011 times
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.

#15832 (ツ) KyberMax
Last edited: 24.04.2019 by KyberMax, read: 5007 times

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.

#15833 (ツ) KyberMax
Last edited: 25.04.2019 by KyberMax, read: 4991 times

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.

#15834 (ツ) johnfound
Last edited: 25.04.2019 by johnfound, read: 4978 times
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.

#15835 (ツ) KyberMax
Created 25.04.2019, read: 4970 times
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.

#15836 (ツ) johnfound
Created 26.04.2019, read: 4968 times
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

#15837 (ツ) KyberMax
Last edited: 26.04.2019 by KyberMax, read: 4959 times
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.

#15838 (ツ) KyberMax
Last edited: 27.04.2019 by KyberMax, read: 4949 times

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

#15839 (ツ) johnfound
Created 27.04.2019, read: 4947 times
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.

#15840 (ツ) KyberMax
Created 27.04.2019, read: 4943 times
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.

#15841 (ツ) KyberMax
Last edited: 29.04.2019 by KyberMax, read: 4918 times

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".

#15842 (ツ) johnfound
Created 29.04.2019, read: 4916 times
KyberMax

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

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

0 1 2

Error detected
0

AsmBB v3.0 (check-in: a316dab8b98d07d9); SQLite v3.42.0 (check-in: 831d0fb2836b71c9);
©2016..2023 John Found; Licensed under EUPL. Powered by Assembly language Created with Fresh IDE