flat assembler
Message board for the users of flat assembler.

flat assembler > Main > Is handwritten asm more dangerous than compiled C code?

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
ACP



Joined: 23 Sep 2006
Posts: 204
DimonSoft wrote:

But if we switch to a more constructive discussion and take a bigger perspective then maybe we should talk about the size of the i variable in your example as compared to the size of eax and the consequences of this difference for integer overflows? We can move on by discussing whether one’s or two’s complement representation is used in both cases, and again the consequences for integer overflow conditions. Just to begin with.


Please do because I apparently do not follow your way of thinking here.

As for examples you have given:

In the first case the author admits that he had used uninitialized boolean variable thus resulting in this strange behavior. In asm it translates to something like this:
Code:
variable db ?    

and assuming/counting on that assembler will always use zero to fill up space. When it will use other value your code may as well fail (depending how you test for 1 and 0).

Using uninitialized variables is clearly wrong and it is considered a software defect that can lead to software vulnerabilities. So while we have UB here it was error in the source code in the first place that resulted in wrong code generation. You can make exactly the same wrong assumption in asm as well as exactly the same mistake.

Second examples are similar, like in the for loop with off-by-one error at the source code level. You can write exactly the same code using asm introducing the same error - again the cause is human error. Obviously C due to its nature and number of compilers and optimization have a large pool of UB.

As for assemblers inserting some code during assembly process please check out A86 assembler. It had some interesting optimizations (like using mov offset instead of lea) and executable code watermarking.

DimonSoft wrote:
Besides, even in languages with automatic memory management there’re cases when the safeguards are just not enough.


If safeguards would make software secure we wouldn't be talking about software security in this thread - would we? The multi layer security model isn't anything new and it should not be surprising that compilers are following same path. The multiple layers model comes from the true belief that every safeguard can fail so adding another layer may decrease the risk of successful attack. Yet you need a good balance, adding too any layers or adding another layer doing the same does not work obviously. But I am sure you already know it.

Please note that you are actually deny yourself a bit with above statement: you already pointed out that memory management defects like buffer overflows are not the only class of vulnerabilities. Your sentence is actually true also for languages without automatic memory management and safeguards can deal with different types of defects. When stack protection techniques were designed buffer overflows were the most popular and most exploited type of software defects. That is why C compilers do deal with them.

DimonSoft wrote:
Logical errors should be fixed by changing the source code, not by inserting even more code.

Every source code defect should be handled by proper change at source code level. But we are not living in ideal world. People do introduce defects, so safeguards have been invented and introduced to limit defects scope and impact. I think you are missing crucial point in what safeguard purpose is in the first place, hence the whole discussion. Going your path we should disable all WAFs since they are just protecting vulnerable code from attacks. That is not how security works.

Last but not least: I do not play with tricky question, instead - as stated previously - I find this topic extremely interesting; there are relatively very few people who actually deal with secure coding on assembly level and so I am hoping to learn something new. [/code]
Post 24 Sep 2018, 19:01
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1315
ACP wrote:
Be so kind and reread all my above posts please - you will find exactly the same statement except not a single example taken out of context. Honestly speaking I fail to see how:
Code:
int i;
i++;    

differs from
Code:
inc eax    

in terms of integer overflow case for example. Could you please explain it?
Signed arithmetic overflow is undefined behavior in C/C++. Only unsigned numbers are defined to "wrap around" like in asm.

This problem is obviously made worse by incompetent people who use "int" or signed types where they shouldn't be signed or even "int" in the first place (e.g. array indices on arbitrary input), because they follow some stupid Google "coding style" garbage.

Signed types are just evil and should be avoided unless you *need* them to be signed. And yes, this goes against the crap spewed by non-C programmers on stack overflow which tell you to use signed everywhere. Even C++ is infected with that mentality.

ACP wrote:
In the first case the author admits that he had used uninitialized boolean variable thus resulting in this strange behavior. In asm it translates to something like this:
Code:
variable db ?    

and assuming/counting on that assembler will always use zero to fill up space. When it will use other value your code may as well fail (depending how you test for 1 and 0).
The assembler doesn't zero anything. That's reserving space and not even stored on disk, the Operating System loader will zero it on load. And anyway p && !p can't be true at the same time here.

ACP wrote:
Using uninitialized variables is clearly wrong and it is considered a software defect that can lead to software vulnerabilities. So while we have UB here it was error in the source code in the first place that resulted in wrong code generation. You can make exactly the same wrong assumption in asm as well as exactly the same mistake.
You can't make the same "wrong assumption" in asm since there's no undefined behavior there. However you can probably make a lot of other wrong assumptions so half of your point is valid.

ACP wrote:
Every source code defect should be handled by proper change at source code level. But we are not living in ideal world. People do introduce defects
Exactly, people introduce defects. People. Not the language.

Like I said, the problem is between chair and keyboard.

ACP wrote:
Going your path we should disable all WAFs since they are just protecting vulnerable code from attacks. That is not how security works.
I don't know what WAFs is, but I really detest the stack checking "features" in compilers and really wish they would just go the hell away on release builds since they bloat the code and slow down performance, even if the code is perfectly safe. Pisses me off.
Post 24 Sep 2018, 20:51
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 451
Location: Belarus
ACP wrote:
DimonSoft wrote:

But if we switch to a more constructive discussion and take a bigger perspective then maybe we should talk about the size of the i variable in your example as compared to the size of eax and the consequences of this difference for integer overflows? We can move on by discussing whether one’s or two’s complement representation is used in both cases, and again the consequences for integer overflow conditions. Just to begin with.
Please do because I apparently do not follow your way of thinking here.

I’ll just start here to avoid citing half of the standard. Just so that you know the direction to dive deeper. The size of char type is not 8 bits. It is only at least CHAR_BIT bits and CHAR_BIT should be at least 8. There’re platforms with 9 bits, 16 bits, etc.

short int is not guaranteed to use two’s complement representation. That’s why the range of values is [–32767; 32767], lower bound is not –32768 as you might expect. And relying on the value being inside the type range is stepping into the UB land. If a compiler notices, it is free to perform any changes to the code. Emphasis: any. BTW, the range is only the minimal range. If you somehow rely on short being 2 bytes in size and allocate memory for it dynamically, congratulations, you’ve just introduced a potential security bug.

Want to write perfectly valid C code that will never break when compiled for another platform? Don’t forget that radix of exponent representation in floating point types is FLT_RADIX, which is at least 2.

I can list this stuff almost infinitely. Now tell me this language can be used to write safe code.

ACP wrote:
Using uninitialized variables is clearly wrong and it is considered a software defect that can lead to software vulnerabilities. So while we have UB here it was error in the source code in the first place that resulted in wrong code generation. You can make exactly the same wrong assumption in asm as well as exactly the same mistake.

Second examples are similar, like in the for loop with off-by-one error at the source code level. You can write exactly the same code using asm introducing the same error - again the cause is human error. Obviously C due to its nature and number of compilers and optimization have a large pool of UB.

I predicted this answer:
DimonSoft wrote:
And your demand for secure C/C++ code with unwanted software defect is either a trick to later say “Ha-ha! It’s not a valid/secure C/C++ code since it has undefined behaviour!” or…

If we define “valid C/C++ program” as “bugless C/C++ program”, then you’re right. Oops, but that applies to any other language, including assembly.

But we’ve been talking about which language makes it easier to avoid security vulnerabilities. If a silly mistake becomes a security vulnerability, I’d prefer to avoid such a language/compiler for any production code.

Like I said (and Furs has already doubled that), in assembly you won’t get (p) and (!p) both true at the same time. Because it interprets your program as is, without trying to be smarter than you.

UB in C/C++ is basically a way to achieve amazing performance by allowing the optimizer to rewrite your code whenever you haven’t proved well enough that you know what you’re doing. It quickly turns compiler from being an instrument that assists in programming to being an opponent in a strange chess game where a tiny mistake might look like a valid reason to optimize and change your program’s behaviour in some corner case that will be detected only after the nuclear station explodes.

ACP wrote:
As for assemblers inserting some code during assembly process please check out A86 assembler. It had some interesting optimizations (like using mov offset instead of lea) and executable code watermarking.

Now what? FASM also does that (say, choosing a shorter instruction). Does that change the program logic arbitrarily? How does that compare to inserting pieces of code that sometimes even perform calls to separate procedures?

I’m OK with x div 2 being replaced with x shr 1 if that’s applicable for the operand type and doesn’t change the logic. Should I be OK with introducing code that’s not under my control and that involves operations on the stack thus changing the structure of a stack frame? Should I be OK when it turns my media player into a calculator? When should I start complaining?

ACP wrote:
If safeguards would make software secure we wouldn't be talking about software security in this thread - would we? The multi layer security model isn't anything new and it should not be surprising that compilers are following same path. The multiple layers model comes from the true belief that every safeguard can fail so adding another layer may decrease the risk of successful attack. Yet you need a good balance, adding too any layers or adding another layer doing the same does not work obviously. But I am sure you already know it.

Shouldn’t it then insert checks for pointer parameters that are dereferenced inside functions for not being NULL pointers? Why?

Quote:
When stack protection techniques were designed buffer overflows were the most popular and most exploited type of software defects. That is why C compilers do deal with them.

I wonder what language had most problems with buffer overflows. Maybe some language that doesn’t have String as First-Class Citizen? Some language that doesn’t have Array as First-Class Citizen? Or some language that pretends to have String (std::string) but fails to implement concatenation when the first operand is a string literal? Some language that still pretends to be a high-level cross-platform language? Some language that is still considered to be low-level compared to others? Some language in which it is quite painful to debug because of tons of junk code (safeguards) that differs between compilers?

ACP wrote:
I think you are missing crucial point in what safeguard purpose is in the first place, hence the whole discussion. Going your path we should disable all WAFs since they are just protecting vulnerable code from attacks. That is not how security works.

I do understand the role of safeguards. I just absolutely disgust the solutions that do not really solve the problem (or solve its easy part) but just make one think (s)he is safe with them, also getting in the way from time to time.

And I also can’t agree that having such a feature makes a language safer. It just makes a programmer feel safer. Which is bad.

Quote:
who actually deal with secure coding on assembly level and so I am hoping to learn something new.

What I’m trying to say here is that secure coding is language-independent. Language is just a way to express what a program should do. Custom implementations are just dialects. Since the nature of buffer overflow or any other kind of vulnerability stays the same, their prevention is basically the same in all languages, just expressed with different words.
Post 24 Sep 2018, 22:36
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 451
Location: Belarus
Furs wrote:
ACP wrote:
Using uninitialized variables is clearly wrong and it is considered a software defect that can lead to software vulnerabilities. So while we have UB here it was error in the source code in the first place that resulted in wrong code generation. You can make exactly the same wrong assumption in asm as well as exactly the same mistake.
You can't make the same "wrong assumption" in asm since there's no undefined behavior there. However you can probably make a lot of other wrong assumptions so half of your point is valid.

Well, to play fair I should insert a note here that in assembly you actually can have UB. Kind of. For example, most flags are explicitly said to have undefined values after an integer division. There’re lots of cases. The difference is that an assembly compiler (assembler) is not given right to make arbitrary changes to the code whenever you hit such a case.

Well, to be even more precise, such cases are not undefined behaviour. In terms of C/C++ it would be called “implementation-defined behaviour” or “unspecified behaviour”. In C/C++ these two do not make the program invalid, unlike UB. In fact, a program with UB is not considered to be a valid C/C++ program even though it’s written with the C/C++ syntax. I find it quite funny to divide programs written in a language into valid and invalid based on whether there’s a logical error in it. Then you can say it’s impossible to write a buggy program in your language, because any program having a bug doesn’t count as C/C++ program.
Post 24 Sep 2018, 22:51
View user's profile Send private message Visit poster's website Reply with quote
ACP



Joined: 23 Sep 2006
Posts: 204
I will quickly recap since my main point is lost in all those rants. Assembly language is not more secure than other language. Take look at first example with boolean variable: the only thing that stops you from writing code similar to the one generated by C compiler is knowledge, not the language itself. End of story. If you don't understand this fact you should not be talking about secure programming at all because you are becoming part of FUD movement.

To recap some points:
1. I find it really odd that someone who doesn't know what WAF (Web Application Firewall) is talking about secure coding.

2. I find it even more strange when I hear that C compiler safeguards results in bloated code. At least in case of GCC and Visual Studio compilers you can disable all mentioned safeguards including those introduced by the linker to exploit operating system security properties. Maybe there is another C/C++ compiler that does not allow it, if so I would like to learn it's name and version. As for those 2 compilers repeating "bloated code" mantra just means that the programmer can't handle correctly tools he is using or he is criticizing.

3. Security is about thinking about out-of-the-box. You guys select simple cases that fits your way of thinking. As for using
Code:
db ?    
you are wrong again at least for a very simple case, since you assume that executable file format handles uninitialized variables sections and the OS loader does the same. How about good old COM format from MS-DOS? FYI you can use data directives in flat binaries as well for shellcode for example. You also assumes that OS loader works the same on the same (like it never gets updated for example) and different platforms and that the code will also always run in the same, non-hostile environment which is clearly wrong assumption. There two great presentation on that topic for PE format:
https://media.blackhat.com/bh-us-11/Vuksan/BH_US_11_VuksanPericin_PECOFF_Slides.pdf
and
https://docplayer.net/34839119-Pe-specification-vs-loader.html
Post 25 Sep 2018, 09:03
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6996
Location: Kraków, Poland
DimonSoft wrote:
Well, to play fair I should insert a note here that in assembly you actually can have UB. Kind of. For example, most flags are explicitly said to have undefined values after an integer division. There’re lots of cases.
It is also possible to get an undefined value of general-purpose register, like when BSF is used with 0 as input. Another example of the importance of input range checks.
Post 25 Sep 2018, 10:46
View user's profile Send private message Visit poster's website Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 1315
ACP wrote:
1. I find it really odd that someone who doesn't know what WAF (Web Application Firewall) is talking about secure coding.
It's not odd at all. We're talking about real programmers and real applications here, not "Web applications" and other garbage.

ACP wrote:
2. I find it even more strange when I hear that C compiler safeguards results in bloated code. At least in case of GCC and Visual Studio compilers you can disable all mentioned safeguards including those introduced by the linker to exploit operating system security properties. Maybe there is another C/C++ compiler that does not allow it, if so I would like to learn it's name and version. As for those 2 compilers repeating "bloated code" mantra just means that the programmer can't handle correctly tools he is using or he is criticizing.
Who said you can't disable it? I'm talking about already-built binaries, not your own.

ACP wrote:
3. Security is about thinking about out-of-the-box. You guys select simple cases that fits your way of thinking. As for using
Code:
db ?    
you are wrong again at least for a very simple case, since you assume that executable file format handles uninitialized variables sections and the OS loader does the same.
It's not an assumption when you know this to be a fact seeing as you specifically code for that platform.

I mean what's next? You "assume" the target is x86 family and thus code is wrong cause it won't compile for ARM?

ACP wrote:
You also assumes that OS loader works the same on the same (like it never gets updated for example) and different platforms and that the code will also always run in the same, non-hostile environment which is clearly wrong assumption. There two great presentation on that topic for PE format:
https://media.blackhat.com/bh-us-11/Vuksan/BH_US_11_VuksanPericin_PECOFF_Slides.pdf
and
https://docplayer.net/34839119-Pe-specification-vs-loader.html
I've no idea what you're talking about.

Zero-initialization is defined behavior. It won't "change in the future" because it will break compatibility. That's like worrying about them changing the format of PE itself which would break any program anyway. It's not just PE either.

Honestly, you remind me of people who "don't trust the API or system calls" and then make rigorous checks after them "just to be safe" even if they're documented in a certain way. Or maybe also save all the registers before calling an API, you can't trust it to save the callee-saved registers after all right? Let's not assume it will save them and cause security vulnerabilities. Rolling Eyes

(and yes, there ARE people who think that way)
Post 25 Sep 2018, 14:18
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16127
Location: Hyperborea
The OS has full control over your app so there is little to be gained by not trusting it. Since the OS could simply nullify all attempts to try and trick it. Your app would never know what happened.

Trust your OS and its APIs. They are there to help you. If you don't trust the OS then you might as well not run it. I'm looking at you Win10.
Post 25 Sep 2018, 14:34
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 451
Location: Belarus
ACP wrote:
I will quickly recap since my main point is lost in all those rants. Assembly language is not more secure than other language.

… but certain languages make it easier to mess things up unintentionally.

ACP wrote:
Take look at first example with boolean variable: the only thing that stops you from writing code similar to the one generated by C compiler is knowledge, not the language itself. End of story. If you don't understand this fact you should not be talking about secure programming at all because you are becoming part of FUD movement.

The example is about making a mistake unintentionally, and the consequences of doing so in different languages. If you don’t understand how a language that makes it possible to have b and !b being true at the same time breaks code safety, think about b being a security check. Then think about the possibility of having similar situations in more tricky cases, like those Raymond Chen talks about. The Standard doesn’t even list all of them!

UB is the topic that most people who love C/C++ are not aware of. Talking about this language feature is not FUD, it is spreading information about something that might (and does!) screw up software reliability and security. Is it FUD to talk about nuclear weapons being available to everyone?

Quote:
1. I find it really odd that someone who doesn't know what WAF (Web Application Firewall) is talking about secure coding.

I find it really odd that someone who doesn’t know about the variability of C/C++ types and consequences of triggering UB in these languages is talking about them. You see my point, right? My master degree dissertation was about applying static analysis to SQL-injection vulnerabilities’ detection, and I’ve obviously seen and analyzed firewall-style techniques in this field, but I personally haven’t seen this acronym to be widely used in this field (which is exactly in the sphere of web-application security). From what I can tell, it is more frequently used in “non-technical” discussions of security, i.e. discussions where prevention measures are discussed without going into serious details of attack mechanisms. I guess, Furs is from quite different field of programming which doesn’t prevent him to hve knowledge about security stuff related to his field.

Besides, you don’t have to be a cow to tell that milk is spoiled.

Quote:
2. I find it even more strange when I hear that C compiler safeguards results in bloated code. At least in case of GCC and Visual Studio compilers you can disable all mentioned safeguards including those introduced by the linker to exploit operating system security properties. Maybe there is another C/C++ compiler that does not allow it, if so I would like to learn it's name and version. As for those 2 compilers repeating "bloated code" mantra just means that the programmer can't handle correctly tools he is using or he is criticizing.

You disable them and now you’re debugging a completely different version of your program. Let’s talk about software reliability and its formal verification? Sadly, not all bugs can be fixed without looking at disassembly of your program, unless you write some simple stuff. Skipping safeguards and stuff like that quickly becomes a nightmare.

Quote:
3. Security is about thinking about out-of-the-box. You guys select simple cases that fits your way of thinking. As for using
Code:
db ?    
you are wrong again at least for a very simple case, since you assume that executable file format handles uninitialized variables sections and the OS loader does the same.

Nobody did. Reread the topic. And nobody said the author of the article expected the variable to be initialized to 0 or any other particular value. Well, it was you who assumed he did.

The author was upset by the fact that the language allows two mutually exclusive situtations to be simultaneous just because of a small bug.

Quote:
How about good old COM format from MS-DOS? FYI you can use data directives in flat binaries as well for shellcode for example. You also assumes that OS loader works the same on the same (like it never gets updated for example) and different platforms and that the code will also always run in the same, non-hostile environment which is clearly wrong assumption.

Could you please cite the posts where anyone assumed that?
Post 25 Sep 2018, 20:05
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
Tomasz Grysztar wrote:
DimonSoft wrote:
Well, to play fair I should insert a note here that in assembly you actually can have UB. Kind of. For example, most flags are explicitly said to have undefined values after an integer division. There’re lots of cases.
It is also possible to get an undefined value of general-purpose register, like when BSF is used with 0 as input. Another example of the importance of input range checks.


This is new to me. I have always assumed that assembly is WYSIWYG, now there are/is undefined behavior in assembly, is it good to code in asm as I try to avoid undefined behavior or should I go back to code in C?
Post 25 Sep 2018, 23:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16127
Location: Hyperborea
For the x86 CPU there are instructions that have some undefined results, as already stated by others here. But this isn't necessarily true for all the other CPUs. Indeed I would suspect that the x86 CPUs are the exception here, most other CPUs precisely define the outcome of every instruction for all input values.
Post 26 Sep 2018, 01:21
View user's profile Send private message Visit poster's website Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 60
Tomasz Grysztar wrote:
ACP wrote:
In assembly language nothing will stop you from passing to small buffer or missing format string for sprintf line function.
I would even say that assembly can be at least as insecure as all other languages combined, because for any unsafe code you could create in another language, you can also do the same in assembly. Wink


You cannot create undefined behavior Wink
That is you can always predict what code will do no matter.
Post 26 Sep 2018, 03:07
View user's profile Send private message Reply with quote
Melissa



Joined: 12 Apr 2012
Posts: 60
Tomasz Grysztar wrote:
DimonSoft wrote:
Well, to play fair I should insert a note here that in assembly you actually can have UB. Kind of. For example, most flags are explicitly said to have undefined values after an integer division. There’re lots of cases.
It is also possible to get an undefined value of general-purpose register, like when BSF is used with 0 as input. Another example of the importance of input range checks.


That's not undefined behavior. Undefined behavior is when compiler is free to do anything
including completely unrelated things.
famous example:
Code:
void f(char* p)
{
  char tmp = *p;
 if(!p)/*do something*/
}
    

compiler completely eliminated `if` because dereferencing p with value of NULL,
causes undefined behavior. You can't do that in assembly.
Actually programmer new that at address of NULL(in this case 0) is some
special value that requires action. Thinking as assembly programmer
he wanted to do something in that case. If he programmed in assembly
everything would be fine. But alas in C, this is undefined behavior and
his code was not executed causing code malfunction. This is why
assmebly is safer then C.
What's even worse program was probably tested in debug build, and error
showed only in release build. Can't happen in assembly.
Post 26 Sep 2018, 03:16
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16127
Location: Hyperborea
It is also possible to make assembly code that performs well and stresses the CPU more than some poorly optimised HLL code. So if the CPU overheats or has less than stellar manufacturing tolerances then the assembly code could trigger random behaviour where the HLL code doesn't.

Another example is the HCF instruction. HLL code never uses it so doesn't cause any problem. So in this case the assembly code can definitely be more "dangerous" than C code.
Post 26 Sep 2018, 06:31
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 6996
Location: Kraków, Poland
revolution wrote:
For the x86 CPU there are instructions that have some undefined results, as already stated by others here. But this isn't necessarily true for all the other CPUs. Indeed I would suspect that the x86 CPUs are the exception here, most other CPUs precisely define the outcome of every instruction for all input values.
From what I have seen, ARM manuals contain many mentions of "UNPREDICTABLE" behavior in various context. I'd say they even pay more attention than Intel manuals to mark such areas with with unified term.

Another example, AVR architecture. These manuals do not use "unpredictable" term, only "undefined" one. Nevertheless, it lists many instructions that give undefined result, like:
Code:
LD r26, X+
LD r27, X+
LD r26, -X
LD r27, -X    


Melissa wrote:
You cannot create undefined behavior Wink
That is you can always predict what code will do no matter.
There are states or values that are officially characterized by CPU manufacturers as unpredictable. Even if you are able to predict the result on a specific implementation, by specification you should not - any other implementation may break your assumption.
Post 26 Sep 2018, 07:07
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16127
Location: Hyperborea
Tomasz Grysztar wrote:
revolution wrote:
For the x86 CPU there are instructions that have some undefined results, as already stated by others here. But this isn't necessarily true for all the other CPUs. Indeed I would suspect that the x86 CPUs are the exception here, most other CPUs precisely define the outcome of every instruction for all input values.
From what I have seen, ARM manuals contain many mentions of "UNPREDICTABLE" behavior in various context. I'd say they even pay more attention than Intel manuals to mark such areas with with unified term.
You are correct. fasmarm catches all those invalid encodings so that the programmer can't shoot themselves in the foot accidentally. But of course the programmer is also free to use db, du, dw, etc. to create any encoding they wish to. But for valid encodings I think that ARM does define all possible outputs.
Post 26 Sep 2018, 07:19
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
revolution wrote:
Tomasz Grysztar wrote:
revolution wrote:
For the x86 CPU there are instructions that have some undefined results, as already stated by others here. But this isn't necessarily true for all the other CPUs. Indeed I would suspect that the x86 CPUs are the exception here, most other CPUs precisely define the outcome of every instruction for all input values.
From what I have seen, ARM manuals contain many mentions of "UNPREDICTABLE" behavior in various context. I'd say they even pay more attention than Intel manuals to mark such areas with with unified term.
You are correct. fasmarm catches all those invalid encodings so that the programmer can't shoot themselves in the foot accidentally. But of course the programmer is also free to use db, du, dw, etc. to create any encoding they wish to. But for valid encodings I think that ARM does define all possible outputs.


How can I completely avoid undefined behavior? Is this even possible?
Post 26 Sep 2018, 11:14
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16127
Location: Hyperborea
wean_irdeh wrote:
How can I completely avoid undefined behavior? Is this even possible?
In what system are you referring to? Most of the links in this topic to C compilers talk about how it is nearly impossible to know for sure that you don't have undefined behaviour. But that is only considering the language used for the source. Since there are other ways to get undefined behaviour (e.g. from the CPU and its memory system) then perhaps such a goal is impossible.
Post 26 Sep 2018, 12:29
View user's profile Send private message Visit poster's website Reply with quote
wean_irdeh



Joined: 12 Sep 2018
Posts: 12
revolution wrote:
wean_irdeh wrote:
How can I completely avoid undefined behavior? Is this even possible?
In what system are you referring to? Most of the links in this topic to C compilers talk about how it is nearly impossible to know for sure that you don't have undefined behaviour. But that is only considering the language used for the source. Since there are other ways to get undefined behaviour (e.g. from the CPU and its memory system) then perhaps such a goal is impossible.


I mean in assembly, also there is a paper describing formal verification effort on ARMv8, does this mean the ARMv8 assembler would be free from undefined behavior?
Post 26 Sep 2018, 14:05
View user's profile Send private message Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 547
It's not dangerous per se, but rather it is easier to make mistakes (or intentional 'mistakes') in ASM if one is not careful enough. A pseudo example;
Code:
mov rdi,0x007ce0fffffffe    ;a pointer to some string variable
add edi,2                   ;oops!    

Looks syntactically / arithmetically legit, but its a big no. You can give this bug any name you think fit because it fits into any types of bugs you can think of. This is no undefined behavior. It is simply being rude Very Happy
Post 26 Sep 2018, 18:33
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2018, Tomasz Grysztar.

Powered by rwasa.