Microsoft Macro Assembler 1.0

Discussions on programming older machines

Re: Microsoft Macro Assembler 1.0

Postby Brutman » Wed Feb 16, 2011 8:59 am

Wow ... I can't let that post go!

Why on earth should I have to remember what register is good at doing what? I have found the limitations and restrictions to be confusing; it is like programming in the stone ages. Having all of these constraints on registers just makes compiler design and implementation more difficult too. But back in the 1970s it probably saved on transistor count, so it was tolerated.

Addressing is an entirely different problem. The use of segment registers makes it easier to relocate code. This is great for the small programming model, where your COM file is basically a memory image of your program. But it breaks on larger programs, which is why EXE files go through a relocation process on loading. Back in 1981 when memory was at a premium designing code to be as compact as possible made sense, but we've been suffering ever since from reduced productivity - near calls vs. far calls and segment addressing are much more difficult to work with than a flat memory model. Once again it was a product of the times - nobody would design a processor like that in the 80s or 90s.

I don't understand the criticism of PPC being slower at calculating offsets - it's just an ALU operation. Two have two pointers (integer values) in two registers, and you subtract.

If you are referring to the use of segments as a poor man's memory protection and that using segments the way a real mode 8088 does is superior to the memory management unit on a more modern machine works, well, that's not comparing apples to apples. Yes, having a segment offset wrap around and corrupt only your own segment is a limited form of protection, but it really won't matter when that now corrupted process continues to corrupt data elsewhere. A real MMU that offers page lookup and protection is vastly superior, and also allows you to get back to easily relocated code too. (In a modern OS the code is always in the same spot in the memory map, and it's the page table handling of the MMU that gets it into physical memory.)

Once again, the Intel design reflects the design trade-offs of the 70s. Nobody in their right mind would have done such a thing in the 80s. (Coincidentally, that is why we see the first RISC processors in the 80s ..)
Brutman
Site Admin
 
Posts: 951
Joined: Sat Jun 21, 2008 5:03 pm

Re: Microsoft Macro Assembler 1.0

Postby deathshadow60 » Thu Feb 17, 2011 2:55 am

Brutman wrote:Wow ... I can't let that post go!

Why on earth should I have to remember what register is good at doing what?

Spoken like a C programmer :D

Because JHVH forbid the next programmer to come along and deal with the code has ANY clue what registers you are using for what actions... It's a bit like the old joke about how if you give things meaningful names and defined roles, comments become pointless.

Brutman wrote:I have found the limitations and restrictions to be confusing;

I find the "go ahead and use any register for anything" approach to be more confusing -- mind you I come from a Cosmac/6502/Z80/6809 background, where they too have "registers with a purpose". It wasn't just about limiting transistor counts, it was about efficiency of execution and clarity of code. Ever look at 68K code? It's illegible mush, even if it is allegedly "more convenient for compiler developers" (a BS claim IMHO)

Of course all those endless numbered 32 bit registers makes ISR entry/exit SO clean on the memory and bus footprint...

Brutman wrote:Addressing is an entirely different problem. The use of segment registers makes it easier to relocate code. This is great for the small programming model, where your COM file is basically a memory image of your program. But it breaks on larger programs, which is why EXE files go through a relocation process on loading.

Said "relocation" putting functions on a 16 byte boundary with their own segments, so internal to themselves they think they're at offset zero. Makes handling BP a dream and is why .exe's load so fast in the first place.

Brutman wrote:Back in 1981 when memory was at a premium designing code to be as compact as possible made sense, but we've been suffering ever since from reduced productivity - near calls vs. far calls and segment addressing are much more difficult to work with than a flat memory model.

Then why is it that most EVERY major OS and processor since the transition to 32 bit doesn't let you have access to a flat memory model? (unless you cheat and make a selector pointing at address zero with no size limit)

Flat memory models are the antithesis of memory protection without some form of dynamic mapping and run-level descriptors -- and if you're going to take time to block off run-level access to sections of memory, why not leverage a segment-type register as your selector. That way you know WHAT memory restriction is being imposed on your code.

Take writing to video, what's more convenient having a selector pointing at the physical address so that your 32 bit-wide index starts at address zero, or having to waste the time adding the memory offset of the start of RAM and then try to preserve that offset as you do operations? Try that in a scanline video mode to see what hell that can be. MANY times on the Coco, C=64 and Atari I found myself wishing those chips HAD segments when it came to video programming!

Brutman wrote:Once again it was a product of the times - nobody would design a processor like that in the 80s or 90s.

Or you could consider it the precursor to modern memory schemes. 286 protected mode turning segments into selectors allowing for protection with descriptors, which then 386 protected mode gave you the 32 bit offsets off of selectors -- vastly superior to any 'flat' memory scheme.

Brutman wrote:I don't understand the criticism of PPC being slower at calculating offsets - it's just an ALU operation. Two have two pointers (integer values) in two registers, and you subtract.

That shouldn't need a separate operation in the first place. Combined with the increased register count and extra logic needed (and gate flops sucking cpu cycles like candy) it's no wonder a 1ghz G4 can barely run OSX 10.2 competantly even with more RAM than the lord, while a 1.4 Centy Celery (which for the most part is the same speed as a 1ghz P3) can run it like a dream on a single gig. So much for that alleged "G4 is faster" -- yeah, in synthetics with tight loops... put a few extra function calls and some hardcore memory thrashing in there, see how it fares! Ooh look, that allegedly faster/more efficient 1ghz G4 is pwned by a 500mhz PII...)

Brutman wrote:If you are referring to the use of segments as a poor man's memory protection and that using segments the way a real mode 8088 does is superior to the memory management unit on a more modern machine works, well, that's not comparing apples to apples. Yes, having a segment offset wrap around and corrupt only your own segment is a limited form of protection,

Not quite, I'm referring to it as the PRECURSOR to how modern machines handle protection and dynamic memory mapping. I am NOT saying it offerred any protection in the x86 form -- It offerred no protection! What I'm saying is the same register scheme was a natural progression to selectors and protection when they appeared on later x86 family processors like the 286 and 386.

Brutman wrote:A real MMU that offers page lookup and protection is vastly superior

Especially if you have a nice processor to handle 65536 possible protected pages if you have enough RAM to allocate as GDT's... like on a x86.

Brutman wrote:and also allows you to get back to easily relocated code too. (In a modern OS the code is always in the same spot in the memory map, and it's the page table handling of the MMU that gets it into physical memory.)

... and on x86 what registers are used to handle that again? CS, SS, DS, ES, FS and GS...

Brutman wrote:Nobody in their right mind would have done such a thing in the 80s. (Coincidentally, that is why we see the first RISC processors in the 80s ..)

Which of course is why it was the driving force of computer development from 1988 onwards, right. RISC never gained a significant foothold in any market until recently, and they're still a decade behind the curve on actual delivered working chips...

Though in a way RISC did win in the end from the Pentium Pro and AMD K6 onward, since under the hood those and most every chip after are RISC chips that have a CISC preprocessor. Best of both worlds IMHO.

It's amazing how many people would prefer to write three times as much code and chew through RAM like it was candy by going RISC on the ML side -- funny how next to nobody actually writes ASM for ARM or MIPS while you still find people writing ASM for x86. Even funnier since wasn't the point of RISC supposed to be LESS code?
Last edited by deathshadow60 on Thu Feb 17, 2011 3:06 am, edited 1 time in total.
The only thing about Adobe web development products that can be considered professional grade tools are the people promoting their use.
deathshadow60
 
Posts: 62
Joined: Mon Jan 10, 2011 6:17 am
Location: Keene, NH

Re: Microsoft Macro Assembler 1.0

Postby deathshadow60 » Thu Feb 17, 2011 3:05 am

Vorticon wrote:Spoken like a professional programmer :) As a hobbyist programmer on the other hand, the 9900 assembly language was pretty easy to master and fit the bill for a machine that had a maximum RAM of 48K

Which was only made possible by disabling half the data bus and letting the video controller handle all memory accesses, neutering half the instruction set on the CPU?

Vorticon wrote:I still say that in my case the 8088 learning curve seems steeper, and maybe it would have been easier had I not learned 9900 first...

I felt the same way when I went from Z80 and 6809 to 6502... To me the 6502 seems like an unnatural convoluted mess compared to ANYTHING Intel... Though I think what REALLY messed me up was learning the 6809 first. (my all-time favorite processor!) Funny because the Z80 seemed so simple yet powerful compared to the Cosmac. It doesn't help that EVERY processor does things differently, so it does often come down to one's comfort zone. For me 8080,Z80 and x86 are second nature -- they make SENSE... 68K, anything TI, 6502 -- feel like mega-disasters that I can't figure out how they became popular in the first place.

ESPECIALLY the 6502. UHHHG... HATED that processor. Probably why my time with the Vic=20 was limited, and why I skipped the C=64 and Apple's altogether -- but then by the time I actually saw an Apple II in person, it was already a decade out of date. (did anyone other than grade schools actually OWN those? Was it a east-coast vs. west-coast thing?)

Vorticon wrote:Just for kicks, here's a video of Pacman on the TI.

Which one has to put in perspective -- since 99% of the grunt-work there is being handled NOT by it's CPU, but by the sprite-engine built into the TMS9918A... a INSANELY powerful graphics chip for it's time which frankly, could probably have done pacman on a 890khz 6502... especially since the 'alleged' system RAM was actually video memory. (in a configuration a billion times worse than what IBM did on the Jr)

Because a 16 bit processor that stores it's registers in external RAM is SUCH an efficient arrangement... especially when you limit it's 16 bit bus to 256 bytes of memory and then access ALL other ram via the video processor.

But that's the wonders of 70's and 80's computing -- so many corners cut just to try and keep the price under control.
The only thing about Adobe web development products that can be considered professional grade tools are the people promoting their use.
deathshadow60
 
Posts: 62
Joined: Mon Jan 10, 2011 6:17 am
Location: Keene, NH

Re: Microsoft Macro Assembler 1.0

Postby Brutman » Thu Feb 17, 2011 7:41 am

deathshadow60 wrote:
Brutman wrote:Wow ... I can't let that post go!

Why on earth should I have to remember what register is good at doing what?

Spoken like a C programmer :D

Because JHVH forbid the next programmer to come along and deal with the code has ANY clue what registers you are using for what actions... It's a bit like the old joke about how if you give things meaningful names and defined roles, comments become pointless.

Brutman wrote:I have found the limitations and restrictions to be confusing;

I find the "go ahead and use any register for anything" approach to be more confusing -- mind you I come from a Cosmac/6502/Z80/6809 background, where they too have "registers with a purpose". It wasn't just about limiting transistor counts, it was about efficiency of execution and clarity of code. Ever look at 68K code? It's illegible mush, even if it is allegedly "more convenient for compiler developers" (a BS claim IMHO)

Of course all those endless numbered 32 bit registers makes ISR entry/exit SO clean on the memory and bus footprint...


You know normally I wouldn't look too kindly on a flame war on this site. We've never had one. Not enough traffic, and not enough passion. And most flame wars are stupid and silly. But those were fighting words, so now we are going to get into it. ;-0

Yes - I am a C programmer. Even worse, I've been a C programmer for 20 years, professionally for 18. And my day job is to write C code for use in the C runtime provided by GLIBC. I reek of C ..

And to make it worse, I am a reasonable PowerPC assembler programmer, and have been for nearly as long. And I love having 32 registers, nearly all identical. (There is a dirty little secret with R0, but we'll ignore that for now.)

I am your nemesis.

Almighty God did not intend for anybody to divine the purpose of code by reading straight hex. That's what comments are for! The only thing that the usage of CX tells me when I see it is that the unlucky programmer probably had a loop construct somewhere that interfered the use of CX as a general purpose register. And high level languages, which most of the industry adopted half a century ago, make trying to guess the purpose of code even less of a mystery although proper coding style and comments are still usually necessary and desired.

As for compilers, they hate constraints on register allocation - that adds to the complexity of the compiler. It hurts optimization and increases the time it takes to compile code when the compiler has to honor silly rules; nothing bogus about it.

deathshadow60 wrote:
Brutman wrote:Addressing is an entirely different problem. The use of segment registers makes it easier to relocate code. This is great for the small programming model, where your COM file is basically a memory image of your program. But it breaks on larger programs, which is why EXE files go through a relocation process on loading.

Said "relocation" putting functions on a 16 byte boundary with their own segments, so internal to themselves they think they're at offset zero. Makes handling BP a dream and is why .exe's load so fast in the first place.


The segmenting method that x86 uses works well enough to extend the memory model and to make relocation easy. It fails miserably on the part where it keeps programs from stepping on each other, or from having wrap-around accidents. It's just a constant accident waiting to happen and it makes handling large amounts of data and code tedious. Perfectly suitable for 1981 when code was 5 K and machines had 128, but really nasty for larger programs.

deathshadow60 wrote:
Brutman wrote:Back in 1981 when memory was at a premium designing code to be as compact as possible made sense, but we've been suffering ever since from reduced productivity - near calls vs. far calls and segment addressing are much more difficult to work with than a flat memory model.

Then why is it that most EVERY major OS and processor since the transition to 32 bit doesn't let you have access to a flat memory model? (unless you cheat and make a selector pointing at address zero with no size limit)

Flat memory models are the antithesis of memory protection without some form of dynamic mapping and run-level descriptors -- and if you're going to take time to block off run-level access to sections of memory, why not leverage a segment-type register as your selector. That way you know WHAT memory restriction is being imposed on your code.

Take writing to video, what's more convenient having a selector pointing at the physical address so that your 32 bit-wide index starts at address zero, or having to waste the time adding the memory offset of the start of RAM and then try to preserve that offset as you do operations? Try that in a scanline video mode to see what hell that can be. MANY times on the Coco, C=64 and Atari I found myself wishing those chips HAD segments when it came to video programming!


Which is why 32 bit operating systems don't just implement a flat address space; they implement virtual memory, and they do it on a per process basis. (Each process has it's own address space.) This is a realization that 32 bit flat models where everybody is in the same address space is a bad thing.

deathshadow60 wrote:
Brutman wrote:Once again it was a product of the times - nobody would design a processor like that in the 80s or 90s.

Or you could consider it the precursor to modern memory schemes. 286 protected mode turning segments into selectors allowing for protection with descriptors, which then 386 protected mode gave you the 32 bit offsets off of selectors -- vastly superior to any 'flat' memory scheme.

Brutman wrote:I don't understand the criticism of PPC being slower at calculating offsets - it's just an ALU operation. Two have two pointers (integer values) in two registers, and you subtract.


That shouldn't need a separate operation in the first place. Combined with the increased register count and extra logic needed (and gate flops sucking cpu cycles like candy) it's no wonder a 1ghz G4 can barely run OSX 10.2 competantly even with more RAM than the lord, while a 1.4 Centy Celery (which for the most part is the same speed as a 1ghz P3) can run it like a dream on a single gig. So much for that alleged "G4 is faster" -- yeah, in synthetics with tight loops... put a few extra function calls and some hardcore memory thrashing in there, see how it fares! Ooh look, that allegedly faster/more efficient 1ghz G4 is pwned by a 500mhz PII...)


Simple question - if you want to calculate an offset from one pointer to another, you need to do math.

In a segmented model you need to take the segment registers into account, which may be different. And then you can worry about the offsets. In a flat memory model it's just one operation - no normalization or anything.

In a segmented architecture at best you know you are in the same segment already, and you still have an ALU operation to compute the offset. And at worst you have to normalize pointers because they are in different (and possibly overlapping) segments. So where is the speed disparity?

By the way, that Celeron you speak so highly of is a RISC processor under the covers. Take a look at the architecture - it busts apart your CISC instructions int RISC-like micro-ops that it hides. Which allows it to use shadow registers (gasp! unmarked general purpose registers!), multiple pipelines, store queues, etc.

deathshadow60 wrote:
Brutman wrote:If you are referring to the use of segments as a poor man's memory protection and that using segments the way a real mode 8088 does is superior to the memory management unit on a more modern machine works, well, that's not comparing apples to apples. Yes, having a segment offset wrap around and corrupt only your own segment is a limited form of protection,

Not quite, I'm referring to it as the PRECURSOR to how modern machines handle protection and dynamic memory mapping. I am NOT saying it offerred any protection in the x86 form -- It offerred no protection! What I'm saying is the same register scheme was a natural progression to selectors and protection when they appeared on later x86 family processors like the 286 and 386.

Brutman wrote:A real MMU that offers page lookup and protection is vastly superior

Especially if you have a nice processor to handle 65536 possible protected pages if you have enough RAM to allocate as GDT's... like on a x86.

Brutman wrote:and also allows you to get back to easily relocated code too. (In a modern OS the code is always in the same spot in the memory map, and it's the page table handling of the MMU that gets it into physical memory.)

... and on x86 what registers are used to handle that again? CS, SS, DS, ES, FS and GS...


Sorry - was thinking PowerPC, ARM, MIPs, and all of the other, more sane architectures that implement virtual memory using page tables, not segment registers. Those registers that you mention are holdovers from an architecture 30 years ago. Normal (and I am going to assert x86 is not normal) architectures don't use segment registers - they let the virtual memory system handle that detail.

deathshadow60 wrote:
Brutman wrote:Nobody in their right mind would have done such a thing in the 80s. (Coincidentally, that is why we see the first RISC processors in the 80s ..)

Which of course is why it was the driving force of computer development from 1988 onwards, right. RISC never gained a significant foothold in any market until recently, and they're still a decade behind the curve on actual delivered working chips...

Though in a way RISC did win in the end from the Pentium Pro and AMD K6 onward, since under the hood those and most every chip after are RISC chips that have a CISC preprocessor. Best of both worlds IMHO.

It's amazing how many people would prefer to write three times as much code and chew through RAM like it was candy by going RISC on the ML side -- funny how next to nobody actually writes ASM for ARM or MIPS while you still find people writing ASM for x86. Even funnier since wasn't the point of RISC supposed to be LESS code?


What? RISC has been the direction for chips since the late 1980s, early 1990s. You can't possibly claim that a processor that takes x86 on the surface and busts it into micro-ops is a CISC processor at the core. It is the best of both worlds in that you get to use your ancient x86 instructions, but every modern x86 since the Pentium Pro and the Pentium II are RISC processors under the covers.

RISC beat CISC a long time ago. Intel did a "if we can't beat them, join them" move. AMD did as well, and both were inspired by the NexGen processors.

You may surrender now ...

Mike
Brutman
Site Admin
 
Posts: 951
Joined: Sat Jun 21, 2008 5:03 pm

Re: Microsoft Macro Assembler 1.0

Postby deathshadow60 » Thu Feb 17, 2011 8:52 am

Brutman wrote:You know normally I wouldn't look too kindly on a flame war on this site.

It's only a flame war when someone takes it personally - I'm not, I'm hoping you're not either... Of course being a backwoods New Englander I can insult you fifteen ways from sunday and not even be aware I'm doing it... There's an attitude of "rip it all down and build it up again" that can really off-put people who aren't used to the "Wellt, ya cahnt geht theyah frum heeyah..." mentality.

Besides, what did you think the smiley was for ;) -- twas a gentle ribbing. Come on, have a sense of humor about it.

Brutman wrote:Yes - I am a C programmer. Even worse, I've been a C programmer for 20 years, professionally for 18. And my day job is to write C code for use in the C runtime provided by GLIBC. I reek of C ..

My condolances. C and I have never gotten along, I can do it, but the needlessly cryptic syntax, absurdly loose typing and total lack of keyword checking or forward declaration makes it so ridiculously error prone I'm amazed anything written in it even works right in the first place.

But I've been a long-time Wirth fan -- structured semantic syntax, strict typecasting, forward declarations.

It's why my work of the past decade in PHP has basically felt like slumming... especially given how it seems most PHP/HTML/CSS developers just vomit up code any old way.

Brutman wrote:And to make it worse, I am a reasonable PowerPC assembler programmer, and have been for nearly as long. And I love having 32 registers, nearly all identical. (There is a dirty little secret with R0, but we'll ignore that for now.)

Whereas I have trouble keeping track of nine.

Brutman wrote:I am your nemesis.

The anti-Jason? Joy.

Brutman wrote:Almighty God did not intend for anybody to divine the purpose of code by reading straight hex.

Not talking straight hex, I'm talking assembler, not machine language. (and yes, there is a difference). Even understanding the opcodes used on 68K legacy processors looking at PPC source code makes my eyes bleed -- needlessly convoluted and over-complex... usually juggling so much in the air at once it's a miracle the processor can keep track of it, much less the programmer.

Brutman wrote:As for compilers, they hate constraints on register allocation - that adds to the complexity of the compiler. It hurts optimization and increases the time it takes to compile code when the compiler has to honor silly rules; nothing bogus about it.

I've heard that complaint before -- and it makes NO sense to me... less registers means less opcodes and less confusion, making the code SIMPLER to write, not more complex. (though admittedly, a wee bit more memory tied). The times people have trouble coding for it usually coming from not thinking hard enough about breaking the job into smaller tasks and just trying to do too much at once.

Kind of why M$ C# targeting generic x86 is a magnitude of order faster than GCC with processor optimizations turned on? It's one of those things where thanks to GCC having more targets than bullets it's not really very well optimized for any one target -- MOST of the x86 code for it's C operations being disastrously inefficient and poorly thought out. You'd think it was a crappy port from a RISC chip instead of an efficient port to the target processor or something.

(See that Quake III port that was floating around a few years ago that was 20% faster just because it was built using Borland C++ instead of GCC)

I mean it's bad when the inefficient FPC (at least compared to Delphi) can school GCC.

Brutman wrote:The segmenting method that x86 uses works well enough to extend the memory model and to make relocation easy. It fails miserably on the part where it keeps programs from stepping on each other, or from having wrap-around accidents. It's just a constant accident waiting to happen and it makes handling large amounts of data and code tedious. Perfectly suitable for 1981 when code was 5 K and machines had 128, but really nasty for larger programs.

... and a total non-issue once you migrate to using the segment registers as SELECTORS on protected mode CPU's... especially since to 'wrap' you'd either have to screw up your range checking or allocate a size in excess of the available RAM... before you even reach the wraparound you should be out-of-bounds. Once you're in 32 bit on the 386 your offset register is now the max size of available memory. You'd only have that problem if DUMB ENOUGH to do the 'flat memory' trick of allocating a 4 gig descriptor at address 0.

If you are wrapping unintentionally, your code is poorly thought out in the first place. God forbid a coder be expected to include range checking... But of course they don't which is how we get buffer overrun vulnerabilities on everything from two-decade old networking code that's STILL present inside OSX (despite having been fixed on the core BSD it was ripped off of for some decade or so), to something as simple as JPEG decoder logic allowing code elevation.

THANKS C.

Though that's treading into the Wirth vs. AT&T arguement -- do you want the compiler to include range checking of pre-declared variable and element sizes by default completely preventing the CHANCE of a overflow, or do you want the compiler make code that not only fail to range check ANYTHING, but allows typo's, bad or completely lacking memory handling practices, accidental assignments, cross-type assignments with memory overlaps messing up packed registers, etc, etc, etc.. to be turned into an executable that may not show that error until a month or even years down the road when it blows up and screws everyone.

As you can tell, NOT a fan of C dialect languages.

Brutman wrote:Which is why 32 bit operating systems don't just implement a flat address space; they implement virtual memory, and they do it on a per process basis. (Each process has it's own address space.) This is a realization that 32 bit flat models where everybody is in the same address space is a bad thing.

Which was exactly what the 286 added with it's protected mode in 1982... and thus the GPF was born.

Brutman wrote:Simple question - if you want to calculate an offset from one pointer to another, you need to do math.

You mean like "effective addresses" which can be done ON THE FLY to an offset after loading the pointers? (LEA being so efficient it's often used INSTEAD of ADD or SUB?)

Brutman wrote:In a segmented model you need to take the segment registers into account, which may be different.

Which is a problem HOW exactly? Pre-protected mode you shouldn't be screwing with single vars larger than 64k anyways since you're 16 bit.. while 32 bit onward you've got each 16 bit selector having it's own protection and access rules (instead of that mapping nonsense that offers LESS protection if you fake ring-level) with it's own allocated size and a zero index to the start of the allocated memory segment.

Brutman wrote:In a segmented architecture at best you know you are in the same segment already

That is a flawed assumption that should NEVER be done -- EVER. EVAARRR -- if you're thinking that way I can see how you don't like segment registers. Yer not using them right. LxS flavors exist for a reason -- passing a selector AND an offset as a pointer because you should NEVER asusme you are in the same segment -- in fact the different segment registers exist FOR that reason... DS being for your heap and/or read segment, CS being for your code and ES being for your write target. EVERY pointer you pass should ALSO be passing a segment. That's what LES, LDS, etc are FOR.

Brutman wrote:and you still have an ALU operation to compute the offset.

Maybe once at the start, but once you've MADE a pointer you shouldn't be running that calculation again unless it's a EA based on something like BP and an IMMED -- and apart from passing values to calls on your heap and/or stack there's no reason to be doing that... at least so far as a base offset is concerned.

Brutman wrote:By the way, that Celeron you speak so highly of is a RISC processor under the covers. Take a look at the architecture - it busts apart your CISC instructions int RISC-like micro-ops that it hides. Which allows it to use shadow registers (gasp! unmarked general purpose registers!), multiple pipelines, store queues, etc.

Which is basically CISC making RISC useful -- you'll notice I basically said that -- though from the rest of your responses it's almost like you COMPLETELY missed what I said from the latter half of my post on.

Brutman wrote:Sorry - was thinking PowerPC, ARM, MIPs, and all of the other, more sane architectures that implement virtual memory using page tables, not segment registers. Those registers that you mention are holdovers from an architecture 30 years ago. Normal (and I am going to assert x86 is not normal) architectures don't use segment registers - they let the virtual memory system handle that detail.

... and I think that's where we differ really. I HATE page maps. They are such a royal pain in the ass it's no wonder there's a near total dearth of quality low level software or even regular software on anything but x86. Much less they seem MORE prone to memory leaks than selectors -- though with so many people using C or similar languages it's no wonder 99% of software out there bleeds memory like a steel sieve. (It's the best kind of Sieve)

We make fun of Steve for it, but when he did his "Developers, Developers, Developers, Developers" rant, he hit it on the head... and I've rarely come across anyone who does low level stuff on a regular basis that has kind words for ARM, MIPS or PPC.

Brutman wrote:What? RISC has been the direction for chips since the late 1980s, early 1990s. You can't possibly claim that a processor that takes x86 on the surface and busts it into micro-ops is a CISC processor at the core.

You missed what I was saying - I said right there RISC won in the end, but only by putting CISC over it. RISC chips that used RISC-Style instructions with hordes of GP registers as the top-level interface for programmers firmly sat in "also ran" category since it's inception as a twinkle in IBM's eye back in the 70's up until the advent of the smart phone -- and even then there's been little to blow my skirt up. (but then, I've never been a phone person in the first place). ARM continues to feel like a rinky underpowered tinkertoy in everything it's in... I'd have thought by now we'd have handhelds at least as powerful as decade old desktops... which we do in terms of the video hardware (with the overglorified PowerVR chips, shades of 1998, S3 Savage is more video card) but in terms of the CPU in these things, not so much.

In a lot of ways I like to think of the CISC machine atop RISC as a JIT optimizing compiler so that a mere mortal might have a chance of making decent code with it -- something that even most RISC high level language compilers barely manage. (if at all, again, see the fat bloated disaster known as GCC)

But then, I've always hated linking, I've always hated makefiles, and I've always hated the stupidity of having to keep separate header files from my linked library code... NOT that GCC seems to bother with dead code removal from included libraries either just lumping it all in there any old way. (NOT that ANY modern compiler is much better -- Yay for 500k console apps for "hello world")

Brutman wrote:It is the best of both worlds in that you get to use your ancient x86 instructions, but every modern x86 since the Pentium Pro and the Pentium II are RISC processors under the covers.

That is what I said... it's kind of my point. I wouldn't voluntarily program RISC directly in the first place. It takes a CISC front-end to make RISC useful. Of course if you want access to all those extra bits, there's always SSE, SSE2, SSE3, SSE4... The latter two of those making altivec look like training wheels.

Oh, and the PII was not RISC under the hood... Though yes the Pentium Pro was... as was the PIII. In terms of widespread adoption AMD actually beat them to the punch with the K6, though yes, CYRIX was actually ahead of the curve on x86 over RISC.

Though as I said it does come down to comfort zone... Even when I was working as a Apple tech during the G3 and G4 era's (hangs head in shame) I was never once enticed by anything other than x86... From 1982 to now there has never once been a computer on another CPU that had the combination of QUALITY software, CHOICE of software and hardware, EXPANDABILITY of hardware, at a reasonable PRICE to even make me look at them... well, except maybe the Amiga, and that was more for novelty factor than serious computing.

When I did have access to them, I was unimpressed at best, disgusted at worst. This REALLY holds for the G3's and G4's -- but as a service tech I did tend to see them on their worst days.
The only thing about Adobe web development products that can be considered professional grade tools are the people promoting their use.
deathshadow60
 
Posts: 62
Joined: Mon Jan 10, 2011 6:17 am
Location: Keene, NH

Re: Microsoft Macro Assembler 1.0

Postby Brutman » Thu Feb 17, 2011 9:32 am

I grew up in NY, so when I choose to insult somebody they are going to know it. ;-0

A Wirth fan? You enjoy programming in a strait-jacket too? Is there no end to the madness?

C is that pleasant half-way house between prison (Pascal/Modula-2) and assembler. Enough rope to hang yourself with, if you so choose. But enough flexibility as you need, including those evil pointer casts.

For a while at IBM I was a guru of the Cell architecture - 128 registers, and they could do any combination of floating point, integer and vector math. Now that was a hoot .. and yes, the compiler loved it - spilling temporaries to the stack was non-existent. (I get frustrated with Intel code, both modern and old because of the need to spill temp values to the stack. That's even more performance robbing than excessively long epilogs and prologs to functions. Of course you are going to tell me that if I programmed in ASM it wouldn't be a problem. ;-0 )

One note about doing pointer comparisons - if I know that my data structure fits with in a 64K segment and I allocated (or normalized the pointer to it), then I *can* do offset computations and take advantage of the fact that the segment is not an issue. I do this all of the time in my TCP/IP code - certain types of buffers come from single segments and don't consume more than a segment. Otherwise, I'd have to normalize pointers more to do simple offsets and comparisons, and that would suck royally. So yes, normally one should not assume what segment pointers are in. Unless you designed it to be a certain way .. (In a flat model it wouldn't matter - that design decision would not need to be made or enforced.)

RISC is RISC - it didn't win by wrapping itself in CISC. PowerPC was pretty pure at the outset. If anything it grew to be more RISC like in implementation; certain instructions (like those that store or load multiple registers) are now microcoded even. (PowerPC suffers from instruction set bloat, but that's a different problem. Most of them are still small and not microcoded.)

x86 survives because it went RISC under the covers, not because a RISC processor adopted it as a cloak.

And I'm quite sure the P2 is based on the Pentium Pro technology, and thus uses micro-ops. The last of the great hard-coded x86 processors was the P54 (Pentium) - after that they are all RISC under the covers. (http://en.wikipedia.org/wiki/Pentium_II)

Let's call this a draw for now - you are a worthy adversary. We shall spar again ..
Brutman
Site Admin
 
Posts: 951
Joined: Sat Jun 21, 2008 5:03 pm

Re: Microsoft Macro Assembler 1.0

Postby deathshadow60 » Thu Feb 17, 2011 10:17 am

Brutman wrote:I grew up in NY, so when I choose to insult somebody they are going to know it. ;-0

I can see you and I rocking on the porch when someone drives up for directions.
Me: <NH accent>"Ya cahn't geht theyah frum heeya..."</nh>
You: <brooklyn>"Ya got a freaking problem with that?"</ny>

Brutman wrote:A Wirth fan? You enjoy programming in a strait-jacket too? Is there no end to the madness?

I find it easier, it's not a straight-jacket, it's a guide to prevent you from making mistakes. You ignore the guide, and, well... as they used to have written on the map "there be dragons here".

Brutman wrote:C is that pleasant half-way house between prison (Pascal/Modula-2) and assembler. Enough rope to hang yourself with, if you so choose. But enough flexibility as you need, including those evil pointer casts.

I could agree with that if it wasn't so damned cryptic and so prone to letting compile code that frankly, shouldn't be allowed to compile in the first place -- it's such a convoluted mess I'd RATHER program Assembler straight than deal with C -- defeating the point of having a high level language.

Brutman wrote:For a while at IBM I was a guru of the Cell architecture - 128 registers, and they could do any combination of floating point, integer and vector math. Now that was a hoot .. and yes, the compiler loved it - spilling temporaries to the stack was non-existent. (I get frustrated with Intel code, both modern and old because of the need to spill temp values to the stack. That's even more performance robbing than excessively long epilogs and prologs to functions. Of course you are going to tell me that if I programmed in ASM it wouldn't be a problem. ;-0 )

Or using a decent compiler -- if you're dumping temps to memory your task probably isn't broken up into subtasks very well... though by definition high level languages should be keeping ALL vars in mem, but I realize that registers as variables for optimizations have become all the rage -- gotta love it when you try to map a pointer over a variable, read the pointer and it doesn't match because the register didn't flush to RAM yet....

But I realize that's MY x86 mentality disagreeing with the 'lets have dozens of GP registers' one... Of course with write-back cache, L1, L2 and L3 caches, and internal cache times that put bus bandwidth to shame -- it's not like it matters if you use 4 registers or 30 anymore, it's probably going to execute in the same amount of time anyways making both our arguments moot.

Brutman wrote:And I'm quite sure the P2 is based on the Pentium Pro technology, and thus uses micro-ops. The last of the great hard-coded x86 processors was the P54 (Pentium) - after that they are all RISC under the covers. (http://en.wikipedia.org/wiki/Pentium_II)

Odd, I was pretty sure the III was the first intel -- and that even AMD beat intel to the punch on getting it into normal machines. (Lets face it, the pro was a rare beast, not the least due to it's compatibility issues)

Brutman wrote:Let's call this a draw for now - you are a worthy adversary. We shall spar again ..

Heh, we can agree to disagree, that's more progress than most people get.

As I said, it's often about comfort zone -- Some people find x86 and pascal restrictive (straight jacket, cute), others find the 'freedom' of C and RISC to be a confusing blob responsible for most of the bad code in existence because it lets you turn code into binaries that shouldn't have been allowed to compile in the first place. It's akin to the difference between the back-room neckbeard *nix server geeks who were left behind by the computer revolution only to come back in force with dirty hippy rhetoric that only career educators and full-time students are naive enough to fall for, and the hobbyists and companies that supported the hobbyists who drove the REAL computer revolution.

As Patton said, "If everyone is thinking the same, somebody isn't thinking"
The only thing about Adobe web development products that can be considered professional grade tools are the people promoting their use.
deathshadow60
 
Posts: 62
Joined: Mon Jan 10, 2011 6:17 am
Location: Keene, NH

Re: Microsoft Macro Assembler 1.0

Postby Vorticon » Fri Feb 18, 2011 12:24 pm

Ahh... It's all so clear to me now :shock: I'm so glad I stuck with medicine :lol: I'm going to hug my TI now.
Vorticon
 
Posts: 276
Joined: Fri Nov 27, 2009 7:25 am

Previous

Return to Programming

Who is online

Users browsing this forum: No registered users and 1 guest