Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

hardware is still coded with machine/assembly language for efficiency, speed, etc.

Status
Not open for further replies.
No it does not, the difference is that exceptional programmers can make a computer run dozens, hundreds, if not thousands of times more efficiently if they're applied properly. The comparison to the human example you gave would be a runner that can run 1000 miles per hour.

The first rule of Internet postings is that bad analogies are never wrong, just misunderstood. ;)
 
There are rules?! <glances over shoulder suspiciously> I see them, they don't generally bother most.
 
Last edited:
Here are my thoughts as an engineer that has come out of “real” industry and into a very niche engineering market:

One task I had was to re-write a FFT written in C to assembly, to achieve a higher sampling rate. It took me 2 weeks. I managed to get to 60% of the cycles of -o3 optimised C, which is quite an improvement, and I am sure a more competent assembly programmer could have beaten my effort (C and VHDL being my main forte's).

Trouble is, all my projects these days (if commercial) are for low volume niche markets where there is a considerable mark up, so loosing a few pounds for a better micro is not going to hurt anything. I could understand trying to use the cheapest DSP/micro possible for a mass produced gadget, but for my work and hobby projects as of today, I would rather have the time gained by writing in C to use in adding more features, debugging, or in writing better PC interfacing software.

Also I would hate to write a large project in Assembly, I could see it becoming a nightmare. Thankfully TI provided a method of writing a C framework with functions (if you wish) written in assembly, which in my option offers the best of both worlds – non time critical code and the general structure code of the code can be written in C, and bottlenecks can be otpimised in assembly. I am guessing most IDE's and their respective compilers/assemblers also have such functionality.

Also if I ever need precise cycle accurate timing, I would go for a CPLD/FPGA + micro solution rather than a processor based solution. The moment you use 1 interrupt, your adding some timing uncertainty.

It's all horses for courses at the end of the day. Some people want to get a job done in the shortest time (which is where my hobby projects fall in these days), where as others will enjoy (or be forced in industry!) the learning process of using say a slightly underpowered micro to do something impressive.
 
Also if I ever need precise cycle accurate timing, I would go for a CPLD/FPGA + micro solution rather than a processor based solution. The moment you use 1 interrupt, your adding some timing uncertainty.

It's all horses for courses at the end of the day. Some people want to get a job done in the shortest time (which is where my hobby projects fall in these days), where as others will enjoy (or be forced in industry!) the learning process of using say a slightly underpowered micro to do something impressive.

Not always... there are ARM cortex's that are a cycle accurate .... they trade off speed for predictability

Dan
 
Have you ever programmed microcontrollers with C? Can you show an example where ASM "has far more control and precision" than C.

My big assembly accomplishment brought what was supposed to be a PIC 18F (we had the tools for it) micro-second resolution pin scanning program written by a college student doing his senior project using C from 600 bytes and 25 µs resolution down to 400-ish bytes and 15µs resolution by simply replacing integer divisions with shift operations. When that didn't cut it, it was rewritten and assembled in maybe 220 bytes or maybe 250 bytes and (i forget but the worst case sucked)µs resolution using assembly language. IIRC, subsequent optimization brought it down to 182 bytes and 6µs resolution. We didn't have development tools nor time for a chip better suited to the application. The interrupt routines did nothing more than record the RTCC. The final main loop jumped from subtask to subtask using hardware pointers indexed according to machine state.
 
Last edited:
Hi MrT,
It's very hard to know what kind of code a C compiler is going to produce. You can look at the source code for some compilers but i dont know too many people who want to take the time to do that..

Not true. Every embedded C programmer should know what kind of code their compiler produces. And there is no need to look at the compilers source, all you need is to read the documentation and look at the disassembly while debugging step by step.

I started out with microsoft assembler using MASM611 programming 8086, 286 and 386. Then I dabbled with C++ and Visual C++, was not long before I went back to assembly.
Was not impressed with overhead and using someone else's programs that I had no control of or limited amount of control.

Yes, (function call) overhead is the one big drawback with C. I can create a "naked" function in C and use inline ASM if I want full control of the function code.. including entry and exit code. The problem with this is that I still need to know what kind of code my compiler produces and save the current execution context "manually". I once wrote a simple multitasking kernel with C and inline assembly. To make the whole system "for general use", I had to save (and load) the whole execution context on every task switch. This means pushing 32+ registers to the stack and then popping another set of registers from another stack.. waste of time and memory, but that is usually the case when you have to write something that is "general purpose".
 
I once wrote a simple multitasking kernel with C and inline assembly. To make the whole system "for general use", I had to save (and load) the whole execution context on every task switch. This means pushing 32+ registers to the stack and then popping another set of registers from another stack.. waste of time and memory, but that is usually the case when you have to write something that is "general purpose".

I wrote a simple multitasking kernel with a true HLL (Modula-2) called MX2 for the Atari ST about 20+ years ago. Modula-2 was a language designed to write OS software but like C you could still embed assembly. The 68000 used on the ST had a few instructions that could not be virtualized or had hidden processor state and had no real memory protection that made a true multitasking system impossible but you could fake it with most programs.

https://www.atarimagazines.com/startv4n12/multitaskingonst.html
https://www.page6.org/st_lib/standard/st0665.php
https://en.wikipedia.org/wiki/Virtualization

The web never forgets, I found an old email about MX2! https://www.megalextoria.com/usenet-archive/news109f1/b132/comp/sys/atari/st/00018621.html
 
Last edited:
I poked around and found the source code for MX2. It's a mixture of 68000 assembly and the Modula-2 HLL.

code fragment of the classic processor state save and restore low level functions. Like misterT said, there is a lot of overhead to change processes if there are no hardware helpers like shadow registers or vectors.

Code:
IMPLEMENTATION MODULE NEWSYS; (*$S-,$T- *)
FROM           SYSTEM   IMPORT  ADDRESS,CODE,SETREG,REGISTER,ADR;

FROM    GEMDOS  IMPORT  Super,Alloc,Free; 

TYPE           trappointer      =       POINTER TO PROC;
               processpointer   =       POINTER TO ADDRESS;
TYPE           iotype   =       RECORD
                                        p1      : processpointer;
                                        p2      : processpointer;
                                        device  : ADDRESS;
                                END;
VAR            pc,ssv                           : ADDRESS;
               io1,io2                          : processpointer;
               sr,function                      : CARDINAL;
               iotranspointer                   : iotype;
               trap                             : trappointer;
               pr1,pr2,wsp                      : ADDRESS;
               n                                : LONGCARD;
               init                             : BOOLEAN;

PROCEDURE  NEWPROCESS(processProc       :  PROC;
                      workspace         :  ADDRESS;
                      worksize          :  LONGCARD;
                      VAR process       :  ADDRESS);
BEGIN
        IF NOT init THEN
           INITPROCESSES;
        END;
        workspace:=workspace+ADDRESS(worksize);
        SETREG(6,ADDRESS(processProc));
        SETREG(8,workspace);
        CODE(2106H);    (* move.l d6,-(a0) PC *)
        CODE(313cH,0300H);      (* move.w $0300,-(a0)   CCR  *)
        CODE(48e0H,0fffeH);     (* movem.l d0-d7/a0-a6,-(a0) *)
        process:=REGISTER(8);
END        NEWPROCESS;

PROCEDURE  TRANSFER(VAR p1,p2: ADDRESS);
BEGIN      (* pass p1 and p2 as the location of these variables *)
        IF NOT init THEN
           INITPROCESSES;
        END;
           SETREG(0,ADR(p2));
           CODE(2f00H); (* move.l d0,-(sp) *)
           SETREG(0,ADR(p1));
           CODE(2f00H); (* move.l d0,-(sp) *)
           CODE(3f3cH,1); (* move.w #1,-(sp) *)
           CODE(4e49H); (* trap #9 *)
           CODE(0dffcH,0,10); (* add.l #10,sp *)
END        TRANSFER;

PROCEDURE  IOTRANSFER(VAR p1,p2: ADDRESS; device: ADDRESS);
BEGIN      (* pass p1 and p2 as the location of these variables *)
        IF NOT init THEN
           INITPROCESSES;
        END;
           SETREG(0,device);
           CODE(2f00H); (* move.l d0,-(sp) *)
           SETREG(0,ADR(p2));
           CODE(2f00H); (* move.l d0,-(sp) *)
           SETREG(0,ADR(p1));
           CODE(2f00H); (* move.l d0,-(sp) *)
           CODE(3f3cH,2); (* move.w #2,-(sp) *)
           CODE(4e49H); (* trap #9 *)
           CODE(0dffcH,0,14); (* add.l #14,sp *)
END        IOTRANSFER;

(*$P- *)
PROCEDURE       PTRAP; 
BEGIN
        CODE(043374B,2700H); (* disable ints *)
        CODE(48e7H,0fffeH);   (* save regs movem  *)
        CODE(306fH,60); (* move.w 60(a7),a0 get sr *)
        sr:=CARDINAL(REGISTER(8));
        IF sr>3fffH THEN         (* called from supermode, not valid *)
           CODE(4cdfH,7fffH);    (* restore regs movem *)
           CODE(4e73H);          (* rte go back to where we came from *)
        END;

        CODE(4e69H);        (* move.l usp,a1 *)
        CODE(3069H,0);      (* move.w 0(a1),a0 *)
        function:=CARDINAL(REGISTER(8));
        CODE(4e69H);        (* move.l usp,a1 *)
        CODE(2069H,2);      (* move.l 2(a1),a0 *)
        iotranspointer.p1:=REGISTER(8);
        CODE(4e69H);        (* move.l usp,a1 *)
        CODE(2069H,6);      (* move.l 6(a1),a0 *)
        iotranspointer.p2:=REGISTER(8);
        CODE(4e69H);        (* move.l usp,a1 *)
        CODE(2069H,10);     (* move.l 10(a1),a0 *)
        iotranspointer.device:=REGISTER(8);

        CASE function OF
             1  : CODE(4e68H); (* move.l usp,a0 TRANSFER *) (* SAVE *)
                  CODE(0dffcH,0,42H); (* add.l #66,sp *)
                  CODE(2127H); (* move.l -(sp),-(a0) D0 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D1 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D2 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D3 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D4 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D5 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D6 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D7 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A0 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A1 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A2 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A3 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A4 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A5 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A6 *)
                  CODE(3127H); (* move.w -(sp),-(a0) SR *)
                  CODE(2127H); (* move.l -(sp),-(a0) PC *)
                  iotranspointer.p1^:=REGISTER(8); (* set p1 to process *)
                  
                  SETREG(8,iotranspointer.p2^); (* load p2 to a0 RESTORE *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D0 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D1 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D2 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D3 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D4 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D5 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D6 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D7 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A0 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A1 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A2 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A3 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A4 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A5 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A6 *)
                  CODE(3ed8H); (* move.w (a0)+,(sp)+ SR *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ PC *)
                  CODE(9ffcH,0,42H); (* sub.l #66,sp *)
                  CODE(4e60H); (* move.l a0,usp *)
                  CODE(4cdfH,7fffH);    (* restore regs movem *)
                  CODE(4e73H); |        (* rte *)

             2  : CODE(4e68H); (* move.l usp,a0 IOTRANSFER *) (* SAVE *)
                  CODE(0dffcH,0,42H); (* add.l #66,sp *)
                  CODE(2127H); (* move.l -(sp),-(a0) D0 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D1 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D2 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D3 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D4 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D5 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D6 *)
                  CODE(2127H); (* move.l -(sp),-(a0) D7 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A0 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A1 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A2 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A3 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A4 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A5 *)
                  CODE(2127H); (* move.l -(sp),-(a0) A6 *)
                  CODE(3127H); (* move.w -(sp),-(a0) SR *)
                  CODE(2127H); (* move.l -(sp),-(a0) PC *)
                  iotranspointer.p1^:=REGISTER(8); (* set p1 to process *)
                  io1:=iotranspointer.p1;
                  
                  io2:=iotranspointer.p2;
                  SETREG(8,iotranspointer.p2^); (* load p2 to a0 RESTORE *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D0 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D1 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D2 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D3 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D4 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D5 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D6 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ D7 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A0 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A1 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A2 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A3 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A4 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A5 *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ A6 *)
                  CODE(3ed8H); (* move.w (a0)+,(sp)+ SR *)
                  CODE(2ed8H); (* move.l (a0)+,(sp)+ PC *)
                  CODE(9ffcH,0,42H); (* sub.l #66,sp *)
                  CODE(4e60H); (* move.l a0,usp *)
                  trap:=trappointer(iotranspointer.device); (* TRAP ADR *)
                  trap^:=ITRAP; (* set trap to IOTRANSFER int code *)
                  CODE(4cdfH,7fffH);    (* restore regs movem *)
                  CODE(4e73H); |        (* rte *)
        END;

        CODE(4cdfH,7fffH);    (* restore regs movem *)
        CODE(4e73H);          (* rte *)
END             PTRAP;
(*$P+ *)

(*$P- *)
PROCEDURE       ITRAP;
BEGIN
        CODE(043374B,2700H); (* disable ints *)
        CODE(48e7H,0fffeH);   (* save regs movem  *)
        CODE(4e68H); (* move.l usp,a0 TRANSFER *) (* SAVE *)
        CODE(0dffcH,0,42H); (* add.l #66,sp *)
        CODE(2127H); (* move.l -(sp),-(a0) D0 *)
        CODE(2127H); (* move.l -(sp),-(a0) D1 *)
        CODE(2127H); (* move.l -(sp),-(a0) D2 *)
        CODE(2127H); (* move.l -(sp),-(a0) D3 *)
        CODE(2127H); (* move.l -(sp),-(a0) D4 *)
        CODE(2127H); (* move.l -(sp),-(a0) D5 *)
        CODE(2127H); (* move.l -(sp),-(a0) D6 *)
        CODE(2127H); (* move.l -(sp),-(a0) D7 *)
        CODE(2127H); (* move.l -(sp),-(a0) A0 *)
        CODE(2127H); (* move.l -(sp),-(a0) A1 *)
        CODE(2127H); (* move.l -(sp),-(a0) A2 *)
        CODE(2127H); (* move.l -(sp),-(a0) A3 *)
        CODE(2127H); (* move.l -(sp),-(a0) A4 *)
        CODE(2127H); (* move.l -(sp),-(a0) A5 *)
        CODE(2127H); (* move.l -(sp),-(a0) A6 *)
        CODE(3127H); (* move.w -(sp),-(a0) SR *)
        CODE(2127H); (* move.l -(sp),-(a0) PC *)
        io2^:=REGISTER(8); (* set interrupted process to process *)
                  
        SETREG(8,io1^); (* load iotransfer process to a0 RESTORE *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D0 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D1 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D2 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D3 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D4 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D5 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D6 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ D7 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A0 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A1 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A2 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A3 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A4 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A5 *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ A6 *)
        CODE(3ed8H); (* move.w (a0)+,(sp)+ SR *)
        CODE(2ed8H); (* move.l (a0)+,(sp)+ PC *)
        CODE(9ffcH,0,42H); (* sub.l #66,sp *)
        CODE(4e60H); (* move.l a0,usp *)
        CODE(4cdfH,7fffH);    (* restore regs movem *)
        CODE(4e73H);         (* rte *)
END             ITRAP;
(*$P+ *)

PROCEDURE  INITPROCESSES;
BEGIN
        ssv:=0;
        Super(ssv);
        trap:=trappointer(TRAP);
        trap^:=PTRAP;
        Super(ssv);
        init:=TRUE;
END        INITPROCESSES;

BEGIN
END               NEWSYS.
 
The 68000 used on the ST had a few instructions that could not be virtualized or had hidden processor state and had no real memory protection that made a true multitasking system impossible but you could fake it with most programs.

That was an ST limitation, not a 68000 one - the far superior Amiga used a 68000 and multitasked perfectly fine, FAR, FAR better than PC's managed until relatively recently.
 

I love it when people dig up old messages of their own like this (and that one's pretty damn old!) - thanks for a virtual trip down "memory lane" (although my internet experience only dates back to 1993, using pine for email, archie/veronica for gopherspace, and good 'ole ftp - all over a shell connection via Internet Direct)...

:D
 
That was an ST limitation, not a 68000 one - the far superior Amiga used a 68000 and multitasked perfectly fine, FAR, FAR better than PC's managed until relatively recently.

True - as long as you weren't trying to format a floppy (or was it any floppy operation? I forget; maybe I should dig out my 2000 and play with it again - gah, I wonder if the hard drive even works in it anymore?)...

:)
 
Can you show an example where ASM "has far more control and precision" than C.

Any processor that has dedicated instructions like LDIR on Z80 cores to MAC instructions on TMS processors.

Java being an interpreted language is rubbish for any realtime processing where speed is essential.

As for the most complicated ASM program I wrote, Trellis coding data in realtime on a comms links was ambitious and arduous looking back. Easily done on a SHARK or modern ARM cores, but on a 6811 running at 16MHz back in the early nineties, it was a challenge, but I prevailed. I believe these routines are still used as they work, work fast and as of yet there is no requirement to change them.

Then looking at another angle in support of ASM during my career, low power processors running off small batteries. Pager (POCSAG) decoding on a 6805. The longer the processor is awake waiting for synch words and frame addresses due to inefficient programming, then the worse the battery life. That costs sales in an end product.
 
I do not understand why you think C is a high level language.. it really is not far away from ASM. C is the next closest thing to "hardware level" programming. It is very efficient and powerful.. if you would just take some time and learn the language before comparing it to asm.

It's so close that I still prefer to use ASM. You miss out the middle man of a compiler and its bugs. Many of the major players in compilers still have bugs in their compilers that have been reported ages ago. You can also find bugs in the hardware (and they do exist) very quickly if you understand what the CPU is doing because you wrote the low level code and not someone elses interpretation of what you are trying to achieve via some third party library that for example in C++, may use function overloading and make debugging very difficult.
 
It's so close that I still prefer to use ASM. You miss out the middle man of a compiler and its bugs. Many of the major players in compilers still have bugs in their compilers that have been reported ages ago. You can also find bugs in the hardware (and they do exist) very quickly if you understand what the CPU is doing because you wrote the low level code and not someone elses interpretation of what you are trying to achieve via some third party library that for example in C++, may use function overloading and make debugging very difficult.

Yeah.. that's why Linux is full of bugs and breaks down every time you update some software or change hardware.
 
Last edited:
I trust you are not being flippant:)) but you are correct. Linux is a powerful OS but I would never use it on anything critical.
I have a Logitech Touch music player and every time the software is updated, there are more bugs that come to light.
I wouldn't rely on it to play soft music without issue on a date which is why my CD player is still stuck at the back of my Hi-Fi stack :)

Ladies relate to soft romantic music on demand and a glass of chilled wine. Not a techy faffing with a remote trying to remove messages like "cannot connect to 192.168.1 x" from what they (and I eventually) would consider a piece of junk.

It just ruins the moment :)
 
Last edited:
That was an ST limitation, not a 68000 one - the far superior Amiga used a 68000 and multitasking perfectly fine, FAR, FAR better than PC's managed until relatively recently.

I've written a lot of OS systems code for the 680X0 family so I know what I'm talking about.
https://www.cpu-world.com/CPUs/68010/
https://en.wikipedia.org/wiki/Popek_and_Goldberg_virtualization_requirements#Motorola_MC68000

This was the first in the family that didn't require user programs to be aware of the nature of the OS and resources. The Amiga kernels level of multitasking was about as good as you could get with the 68000 but it had no memory paging, no virtual machine or memory and no true hardware protection due to the 68000.
 
Last edited:
I trust you are not being flippant:)) but you are correct. Linux is a powerful OS but I would never use it on anything critical.

I agree that VMS could be better but Linux is running a huge amount of critical infrastructure today.
**broken link removed**
 
Define huge in a quantitative sense nsaspook. You'd also have to define 'critical infrastructure'. The words you use have no measure in the real world, the link you posted supports nothing of your statement. The government has developed many failed programs, and continues to support those which have no value, the fact that the NSA has made these extensions public and analyse of their effectiveness is not supported by any links you've shared.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top