my idea
-
- Posts: 4
- Joined: Tue Oct 29, 2013 3:54 am
my idea
Hi, my name is Ed. A little about myself: I am 22 years old, I am german, I was interested in programming ever since I was 15 years old, even tho I never really program anything useful I kept myself interested over the years. I love programming in ASM because it gives me the feeling of being in total control and also because it gives me much more room to develop own mechanism. To me programming is a lot like playing with LEGO blocks, with the only difference that on the computer I have unlimited amounts of blocks and the fact that whenever I finish a small program it actually can do some sort of task for me, which is amazing. So as you see coding is much more a process of being creative than a way of solving problems to me. Recently I have been getting more interested in operating system development. It is pretty much the low-level-est thing I have ever tried out so far and I love how much possibilities it seems to offer me.
Over the last few days I have been thinking about why people don't like to work with Assembly anymore. People seem to want faster, more abstract high-level languages that can do complex tasks with just a few smart lines of code. I myself have been taking a look at high-level languages, I originally even started out with C++ back when I was still new to programming. I did a little python here and a little javascript there over the last 2 years. The languages are great, don't get me wrong, but I always feel like I am deprecating my creativity by letting libraries and abstractions do the job for me. When you want to get a job done nowadays you just look up some language or library that can do the job for you and then you look up some documentation that tells you how to use those tools appropriately to do whatever you want to for you. I am absolutely horrified by this, it is so straight-forward, it feels like the only thing that matters at the end is that the code works and does what it is supposed todo. No smart puzzling of instructions that is rewarded by more efficient running code, no planing about how data is organized in memory, no own architectures. So incredibly dull and narrow and not at all fun and rewarding.
But I also understand that working with ASM is a total pain as it is tedious, hard to read and slow as heck. Ever tried reverse engineering? Like disassembling some binary and trying to understand its internal mechanics. Boy, that was impossible for me. I didn't even know where to start. You are completely overwhelmed by the sheer size of the code, you loose orientation so quickly. Additional to that you will have trouble remembering, even if its code you wrote yourself, what the code of each part actually does. It seems insane for me wanting to go back to ASM. Also there is the whole think with code not being very compatible across computers, making it hard to share what you have created with other people.
Maybe it doesn't have to be like this. Maybe the problem with ASM is not the language but rather the missing tools and the dependencies for compatibility that you simply can't avoid nowadays. If there was a way to make ASM code more accessible and easier to orientate in, maybe we wouldn't have to be so dependent on libraries and tools doing and optimizing everything for us.
Think of an operating system that is as basic as possible, starts out with almost nothing but basic initialization, a few drivers and an IDE that lets you design the rest of the operating system yourself.
The IDE itself is the main feature of the operating system. It provides information about all instructions, a profiler, a sort of "unit-testing" and a way of live-programming that breaks up the usual development steps of coding -> building -> debugging into a process where all three steps happen simultaneously. Maybe it could even provide some sort of probing-mechanism that could help the user reverse engineer the hardware he is currently working with. This total lack of dependency for documentations and libraries would make the operating system into a personal part of the programmer.
I don't know exactly why this thought fascinates me so much, but I think this would really help stop the general growing disinterest in programming among the newer generation, help solve the issue of PC security and unwanted surveillance and also strengthen the concept of independent software development.
I understand that my idea sounds far fetched. But I'd really like to try to implement something like that and then share it after its reached a stage where people could actually use it and see if people like my approach for operating with computers. I will probably come back every now and then and ask stupid questions about kernel/driver-development as I am not really the ultra-pro hacker that I'd like to be. Meanwhile I'd like to hear what people think about my idea and, if there is any interest, start a discussion about it. What do you think?
Over the last few days I have been thinking about why people don't like to work with Assembly anymore. People seem to want faster, more abstract high-level languages that can do complex tasks with just a few smart lines of code. I myself have been taking a look at high-level languages, I originally even started out with C++ back when I was still new to programming. I did a little python here and a little javascript there over the last 2 years. The languages are great, don't get me wrong, but I always feel like I am deprecating my creativity by letting libraries and abstractions do the job for me. When you want to get a job done nowadays you just look up some language or library that can do the job for you and then you look up some documentation that tells you how to use those tools appropriately to do whatever you want to for you. I am absolutely horrified by this, it is so straight-forward, it feels like the only thing that matters at the end is that the code works and does what it is supposed todo. No smart puzzling of instructions that is rewarded by more efficient running code, no planing about how data is organized in memory, no own architectures. So incredibly dull and narrow and not at all fun and rewarding.
But I also understand that working with ASM is a total pain as it is tedious, hard to read and slow as heck. Ever tried reverse engineering? Like disassembling some binary and trying to understand its internal mechanics. Boy, that was impossible for me. I didn't even know where to start. You are completely overwhelmed by the sheer size of the code, you loose orientation so quickly. Additional to that you will have trouble remembering, even if its code you wrote yourself, what the code of each part actually does. It seems insane for me wanting to go back to ASM. Also there is the whole think with code not being very compatible across computers, making it hard to share what you have created with other people.
Maybe it doesn't have to be like this. Maybe the problem with ASM is not the language but rather the missing tools and the dependencies for compatibility that you simply can't avoid nowadays. If there was a way to make ASM code more accessible and easier to orientate in, maybe we wouldn't have to be so dependent on libraries and tools doing and optimizing everything for us.
Think of an operating system that is as basic as possible, starts out with almost nothing but basic initialization, a few drivers and an IDE that lets you design the rest of the operating system yourself.
The IDE itself is the main feature of the operating system. It provides information about all instructions, a profiler, a sort of "unit-testing" and a way of live-programming that breaks up the usual development steps of coding -> building -> debugging into a process where all three steps happen simultaneously. Maybe it could even provide some sort of probing-mechanism that could help the user reverse engineer the hardware he is currently working with. This total lack of dependency for documentations and libraries would make the operating system into a personal part of the programmer.
I don't know exactly why this thought fascinates me so much, but I think this would really help stop the general growing disinterest in programming among the newer generation, help solve the issue of PC security and unwanted surveillance and also strengthen the concept of independent software development.
I understand that my idea sounds far fetched. But I'd really like to try to implement something like that and then share it after its reached a stage where people could actually use it and see if people like my approach for operating with computers. I will probably come back every now and then and ask stupid questions about kernel/driver-development as I am not really the ultra-pro hacker that I'd like to be. Meanwhile I'd like to hear what people think about my idea and, if there is any interest, start a discussion about it. What do you think?
Re: my idea
Oh, man. You've written so much text but didn't put an informative title, so people have to read it completely to find your main points and whether this topic is interesting for them at all.
> almost nothing but basic initialization, a few drivers and an IDE that lets you design the rest of the operating system yourself.
I can suggest you reading about Forth (z.B.: OpenFirmware) and Lisp systems (GeneraOS, OpenGenera, Emacs, etc).
Btw, don't be afraid of abstractions. Sometimes code in rather high level languages can result in even better machine code than pure-C application because it's easier to analyze such code due to some constraints (for example, if you allow only references and no pointers, you can perform much better alias analysis).
> almost nothing but basic initialization, a few drivers and an IDE that lets you design the rest of the operating system yourself.
I can suggest you reading about Forth (z.B.: OpenFirmware) and Lisp systems (GeneraOS, OpenGenera, Emacs, etc).
Btw, don't be afraid of abstractions. Sometimes code in rather high level languages can result in even better machine code than pure-C application because it's easier to analyze such code due to some constraints (for example, if you allow only references and no pointers, you can perform much better alias analysis).
-
- Posts: 4
- Joined: Tue Oct 29, 2013 3:54 am
Re: my idea
Sorry for the title thing, I wasn't sure there was any way to be more specific.
Thanks for your reply Nable. Even tho I appreciate your hints I am not sure if I did a good job bringing my point across. I guess the only way to be sure is to post a piece of ASM code I wrote a few days ago for my first small 16-bit bootloader:
I spend hours on inventing this routine. Not because I couldn't find a solution, but because I wanted a code that is as fast as possible while providing all the functionality I need. A lot of trying around, alot of thinking about how I can make the code more parallel while maintaining safety. This is the kinda stuff that I enjoy. If only i didn't have to look stuff up on google every 10 seconds, working with the text editor also isn't that nice as well as the fact that I can only imagine what goes on in the CPU while I try to come up with a smart mechanism. If I had a tool that could remove those pains, I'd surely have a lot more fun with this (and I am already having much more fun with this than with any other language).
Thanks for your reply Nable. Even tho I appreciate your hints I am not sure if I did a good job bringing my point across. I guess the only way to be sure is to post a piece of ASM code I wrote a few days ago for my first small 16-bit bootloader:
Code: Select all
;print method utilizing BIOS-function 10h with simple proprietary formating scheme for inserting 16bit hex-values (location indicated by 0x01 value within the string)
;#########################################################################################
;# printing routine ;cx:size,esi:source,optional:arguments on stack(32 bit)
dbg_assert:
mov ebp,esp ;ebp is going to get abused, sit tight
add ebp,02h ;+16bit (pointing to our first (potential) argument now
mov ah,0Eh ;int 10h - 0Eh -> print character (BIOS)
_da_print:
lodsb ;load byte into al
test al,0FEh ;0x01 or 0x00 (test takes less clocks than cmp, from what I read)
jz _da_except ;either 0x01 (our indicator) or zero detected
int 10h ;print character
loop _da_print ;loopie
_da_error:
ret
_da_except:
test al,al ;test zero
jz _da_error ;unexpected termination (zero)
mov bx,[ebp] ;load 16bit value to be printed off stack
add ebp,02h ;set ebp to next (potential) argument
push cx ;cache main counter
mov cx,04h ;set count (16bit -> 4 digits)
_dan_print:
mov dx,bx ;cache value
and dx,0F000h ;4bit mask
rol dx,04h ;rotate masked bits from most significant to least significant
mov al, [n_ascii+edx] ;look up corresponding ascii value
int 10h ;print digit
rol bx,04h ;next 4bit
loop _dan_print ;loopie
pop cx ;retrieve old counter
jmp _da_print ;go back
;#########################################################################################
;# messages
msg_mem db 'Available memory: 0x',01h,00h
;#########################################################################################
;# number to ascii table
n_ascii:
db '0'
db '1'
db '2'
db '3'
db '4'
db '5'
db '6'
db '7'
db '8'
db '9'
db 'A'
db 'B'
db 'C'
db 'D'
db 'E'
db 'F'
Re: my idea
To quote Alfred North Whitehead:EdTheClown wrote: Over the last few days I have been thinking about why people don't like to work with Assembly anymore. People seem to want faster, more abstract high-level languages that can do complex tasks with just a few smart lines of code. I myself have been taking a look at high-level languages, I originally even started out with C++ back when I was still new to programming. I did a little python here and a little javascript there over the last 2 years. The languages are great, don't get me wrong, but I always feel like I am deprecating my creativity by letting libraries and abstractions do the job for me. When you want to get a job done nowadays you just look up some language or library that can do the job for you and then you look up some documentation that tells you how to use those tools appropriately to do whatever you want to for you. I am absolutely horrified by this, it is so straight-forward, it feels like the only thing that matters at the end is that the code works and does what it is supposed todo. No smart puzzling of instructions that is rewarded by more efficient running code, no planing about how data is organized in memory, no own architectures. So incredibly dull and narrow and not at all fun and rewarding.
These high-level language programmers are just being smart. This strategy works to their advantage until they uncover a problem with a low-level library. At that point their lack of low-level knowledge, which is the case for most of them today, makes progress nigh on impossible. Until they get to that point, they're getting more return on their investment in learning to program than you are. However, programmers like you are in a better place to overcome the problems of a broken library. Also programmers like you have a wider frame of reference so you don't have to automatically simplify problems to fit into the high-level language world view.It is a profoundly erroneous truism, repeated by all copy-books and by eminent people when they are making speeches, that we should cultivate the habit of thinking of what we are doing. The precise opposite is the case. Civilization advances by extending the number of important operations which we can perform without thinking about them.
You're like me. Just keep on keeping on. I promise there will come a time when everyone else wants to give up and you're still full of ideas. At that point everyone will see the difference. If you want to spend time working on both levels, then implement high level languages. There's plenty of opportunity to write assembly code and write code that writes assembly code in that arena.
Every universe of discourse has its logical structure --- S. K. Langer.
Re: my idea
But, by making BIOS calls you are using an abstraction, or a library of routines if you prefer. And writing in assembler is another abstraction as, in a way, is using a keyboard and VDU. Really you should be doing this the way that the old-time programmers did - enter each machine instruction on a set of switches as a binary number, and display the results as binary numbers on a set of LEDs.
The simple fact is that abstractions take away some of the mechanical tedium of writing a program and allow one to use your imagination more on what the program is doing rather than the mechanics of specifying exactly how it does it step-by-step. 99% of programmers will produce more efficient code with a high-level language than when writing in assembler - and by that I mean more efficient when actually run rather than theoretically counting clock cycles.
The simple fact is that abstractions take away some of the mechanical tedium of writing a program and allow one to use your imagination more on what the program is doing rather than the mechanics of specifying exactly how it does it step-by-step. 99% of programmers will produce more efficient code with a high-level language than when writing in assembler - and by that I mean more efficient when actually run rather than theoretically counting clock cycles.
Re: my idea
Hi,
On 80x86 CPUs the TEST and CMP instructions take the same amount of time. The difference is whether or not there's an immediate value (which increases instruction size, which can increase instruction/trace cache usage). For example, "test al,al" has no immediate value, while "cmp al,0" does have an immediate value and is therefore a slightly less efficient way to see if AL is zero. Your "test al,0xFE" does have an immediate value and is no better than "cmp al,0x01".
You've got three different cases (0, 1 and other) and two TEST instructions. You could have a single CMP instruction instead. Basically:
In "_da_except"; by doing "add ebp,02h" before "mov bx,[ebp]" (rather than after) you get to remove the initial "add ebp,02h" instruction near the very beginning of the code. Using "mov bx,[ebp]" costs an address size override prefix and isn't necessary for real mode, and that should be "mov bx,[bp]" instead. For the same reason "mov ebp,esp" should be "mov bp,sp", and "add ebp,02h" should be "add bp,02h".
For "loop _da_print", the LOOP instruction is typically done in micro-code and for lots of 80x86 CPUs and it's faster to break this into separate "sub ecx,1" and "je _da_print" instructions.
For "loop _dan_print", it would be better to unroll the loop, which would avoid the (likely micro-coded/slow) LOOP instruction and also avoid the need to save and restore the loop counter (CX).
For "mov al, [n_ascii+edx]" nothing guarantees that the highest 16-bits of EDX are clear (which can cause a general protection fault as you exceed the 64 KiB segment limit). To fix this you should've done "movzx edx,bx" instead of "mov dx,bx". However, there's at least one avoidable address size override prefix (and likely 2 of them) involved. A better idea would be to use BX where you're using DX and use DX where you're using BX, so that you can do "mov al,[n_ascii+bx]" and avoid clearing the highest 16-bits and the address size override.
Now look at the documentation for the BIOS function you're using. Pay special attention to what BH is used for. Most video cards have multiple "display pages", where one is currently visible (and the others aren't, and you can switch from one display page to another quickly). Failing to set BH before calling this BIOS function can/will mean you're printing character/s to a display page that either doesn't exist or isn't visible.
Now think about your ROL instructions - for each digit you do two separate ROL instructions. This can be optimised so that you only do one, sort of like this:
Also the comment at the top (the thing programmers rely on to get the args right) is wrong - you're using SI and not ESI, and the optional args from the stack are 16-bit and not 32-bit.
So... with all this in mind, here's a different version of your code:
Of course it would be faster to not bother with CX at all and always used 0 to terminate the main loop; and faster to split it into 2 separate routines (one for printing a raw ASCIIZ string, and another for printing a 16-bit hex value) where no escape codes are needed; and better to have a third routine for printing an 8-bit hex value (increases things you can use the code for). Here's what that would look like:
Of course in this case you'd need this:
Not only is this faster and smaller than some silly "printf()" swiss army knife thing; for assembly language it's much easier to use and maintain because you don't need to bother with pushing a variable number of optional arguments on the stack (and cleanup after, and stack frames, and branch mispredictions, and...).
Now; re-read all of the above and see if you can figure out where a compiler could've optimised better than you, avoided bugs better than you, and made a silly "printf()" swiss army knife thing much easier for a caller to use.
Cheers,
Brendan
Except it's not as fast as possible..EdTheClown wrote:I spend hours on inventing this routine. Not because I couldn't find a solution, but because I wanted a code that is as fast as possible while providing all the functionality I need.
On 80x86 CPUs the TEST and CMP instructions take the same amount of time. The difference is whether or not there's an immediate value (which increases instruction size, which can increase instruction/trace cache usage). For example, "test al,al" has no immediate value, while "cmp al,0" does have an immediate value and is therefore a slightly less efficient way to see if AL is zero. Your "test al,0xFE" does have an immediate value and is no better than "cmp al,0x01".
You've got three different cases (0, 1 and other) and two TEST instructions. You could have a single CMP instruction instead. Basically:
Code: Select all
cmp al,1
jb .wasZero
je .wasEscape
.wasCharacter:
For "loop _da_print", the LOOP instruction is typically done in micro-code and for lots of 80x86 CPUs and it's faster to break this into separate "sub ecx,1" and "je _da_print" instructions.
For "loop _dan_print", it would be better to unroll the loop, which would avoid the (likely micro-coded/slow) LOOP instruction and also avoid the need to save and restore the loop counter (CX).
For "mov al, [n_ascii+edx]" nothing guarantees that the highest 16-bits of EDX are clear (which can cause a general protection fault as you exceed the 64 KiB segment limit). To fix this you should've done "movzx edx,bx" instead of "mov dx,bx". However, there's at least one avoidable address size override prefix (and likely 2 of them) involved. A better idea would be to use BX where you're using DX and use DX where you're using BX, so that you can do "mov al,[n_ascii+bx]" and avoid clearing the highest 16-bits and the address size override.
Now look at the documentation for the BIOS function you're using. Pay special attention to what BH is used for. Most video cards have multiple "display pages", where one is currently visible (and the others aren't, and you can switch from one display page to another quickly). Failing to set BH before calling this BIOS function can/will mean you're printing character/s to a display page that either doesn't exist or isn't visible.
Now think about your ROL instructions - for each digit you do two separate ROL instructions. This can be optimised so that you only do one, sort of like this:
Code: Select all
rol bx,4 ;Highest 4 bits end up in lowest 4 bits...
mov dx,bx
and dx,0x0F
So... with all this in mind, here's a different version of your code:
Code: Select all
;print method utilizing BIOS-function 10h with simple proprietary formating scheme for inserting 16bit hex-values (location indicated by 0x01 value within the string)
;#########################################################################################
;# printing routine ;cx:size,si:source,optional:arguments on stack(16 bit)
dbg_assert:
mov bp,sp ;bp is going to get abused, sit tight
mov ah,0Eh ;int 10h - 0Eh -> print character (BIOS)
_da_print:
lodsb ;load byte into al
cmp al,1 ;Is it 0x00 or 0x01?
jb _da_error ; yes, 0x00 (unexpected termination)
je _da_except ; yes, 0x01 (escape)
xor bh,bh ;bh = display page = 0 (the default display page)
int 10h ;print character
sub cx,1
jne _da_print ;loopie
_da_error:
ret
_da_except:
add bp,02h ;set bp to next (potential) argument
mov dx,[bp] ;load 16bit value to be printed off stack
rol dx,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for first digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print first digit
rol dx,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for second digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print second digit
rol dx,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for third digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print third digit
rol dx,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for fourth digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print fourth digit
jmp _da_print ;go back
Code: Select all
;#########################################################################################
;# printing string routine ;si:source,optional:arguments on stack(16 bit)
dbg_printString:
mov ah,0Eh ;int 10h - 0Eh -> print character (BIOS)
xor bh,bh ;bh = display page = 0 (the default display page)
lodsb ;load byte into al
test al,al ;Is it string terminator?
je .exit ; yes
.next:
int 10h ;print character
lodsb ;load byte into al
test al,al ;Is it string terminator?
jne .next ; no
.exit:
ret
;#########################################################################################
;# printing 16-bit hex routine ;dx = value to print
dbg_printHex16:
rol dx,8
call dbg_printHex8
rol dx,8
; jmp dbg_printHex8 ;Unecessary (can fall through to next routine)
;#########################################################################################
;# printing 8-bit hex routine ;dl = value to print
dbg_printHex8:
rol dl,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for fourth digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print fourth digit
rol dl,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for fourth digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print fourth digit
ret
Code: Select all
section .data
msg_mem: db 'Available memory: 0x',0
section .text
mov si,msg_mem
call dbg_printString
mov dx,something_from_somewhere
call dbg_printHex16
Now; re-read all of the above and see if you can figure out where a compiler could've optimised better than you, avoided bugs better than you, and made a silly "printf()" swiss army knife thing much easier for a caller to use.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: my idea
Code: Select all
;#########################################################################################
;# printing 16-bit hex routine ;dx = value to print
dbg_printHex16:
rol dx,8
call dbg_printHex8
rol dx,8
; jmp dbg_printHex8 ;Unecessary (can fall through to next routine)
;#########################################################################################
;# printing 8-bit hex routine ;dl = value to print
dbg_printHex8:
rol dl,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for fourth digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print fourth digit
rol dl,4
mov bx,dx
and bx,0x0F
mov al, [n_ascii+bx] ;al = ASCII for fourth digit
;bh = display page = 0 due previous "and bx,0x0F"
int 10h ;print fourth digit
ret
What I would like to point out in general is (not just this): being safe is more important than extreme efficiency especially if being safe can be easily achieved. Another example is "lodsb" instruction that relies on Direction Flag. If we had a well-defined ABI, we could trust that the calling convention requires Direction Flag to be cleared (for example). However, when writing in assembly, this is not usually the case.
-
- Member
- Posts: 5574
- Joined: Mon Mar 25, 2013 7:01 pm
Re: my idea
With all this talk of code optimization, I'm surprised no one tried optimizing away the data table:
Code: Select all
and al, 0x0f
cmp al, 0x0a
sbb al, 0x69
das
Re: my idea
Hi,
In the topic's first post, EdTheClown wrote "Over the last few days I have been thinking about why people don't like to work with Assembly anymore.". Being safe is more important than efficiency; but the entire point of my post was to show EdTheClown that assembly language typically doesn't give you safety or efficiency (which is one of the main reasons why people don't like to work with Assembly anymore).
Cheers,
Brendan
You're right - I forgot the "mov ah,0x0E" at the start of the "dbg_printHex8" routine. That's what I get for writing assembly at 3 AM.Antti wrote:Although this might be considered as pseudocode, it is so complete that someone might use it. Because of that, I want to point out that the BIOS function is undefined if these functions are called without first calling dbg_printString. To make things worse, it is not very unusual that the register ah happens to be 0 for some reason and this would mean that we are calling the Set Video Mode procedure with some unusual video mode (because of typical ASCII code value). Or course, it could be any other "int 0x10" service also.
If needed, I always do basic initialisation at/near the start of my code (like setting segment registers and SP and clearing the direction flag), so that I can avoid having "cld" scattered all over the place (and only need "cld" after using a "std"). I assume EdTheClown does/did the same.Antti wrote:What I would like to point out in general is (not just this): being safe is more important than extreme efficiency especially if being safe can be easily achieved. Another example is "lodsb" instruction that relies on Direction Flag. If we had a well-defined ABI, we could trust that the calling convention requires Direction Flag to be cleared (for example). However, when writing in assembly, this is not usually the case.
In the topic's first post, EdTheClown wrote "Over the last few days I have been thinking about why people don't like to work with Assembly anymore.". Being safe is more important than efficiency; but the entire point of my post was to show EdTheClown that assembly language typically doesn't give you safety or efficiency (which is one of the main reasons why people don't like to work with Assembly anymore).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: my idea
Wise words. It very easy to introduce bugs that are practically impossible with high-level languages. I recently wrote a three-stage boot system in assembly and it seems to work just fine. However, I do not trust it at all. It is worthless at the moment. Now that I have the functionality I need, I will start refactoring it and doing unit tests. It would perhaps take as much time as the writing itself. However, at the end I should have code that has some use. I think the difference between "highly-tested" and "seems to work" code is extremely huge.Brendan wrote:Being safe is more important than efficiency; but the entire point of my post was to show EdTheClown that assembly language typically doesn't give you safety or efficiency (which is one of the main reasons why people don't like to work with Assembly anymore).
-
- Posts: 4
- Joined: Tue Oct 29, 2013 3:54 am
Re: my idea
Hello again, thanks for all the replies. I was amazed at how detailed your knowledge about x86 programming is. Kinda embarrassing that I stated that my code was the best implementation possible and I was proven incorrect. Again, thanks to the people who took the time to analyze and optimize my code while providing these nifty hints.
Even tho a lot was implied about how using high-level languages is the better and safer way I have not given up on my idea of further diving into the world of pure ASM. Already having mentioned some of my main concepts for the IDE I have been wanting to implement I have made a small mock-up image that roughly outlines what I had in mind on what it will look like. You can take a look at it and tell me what you think. A small description of what you are looking at:
-Window top left is the code editor, self-explanatory
-Below something that looks like something out of an instant-messenger, its a smaller text input that automatically formats and inserts the code in
a customize-able pattern.
-Next to it: a small intermediate info on what you are writing/what is selected.
-The ? is a helpful link to a documentation that you can pop-up on any instruction to find data about the particular instruction you want to use
-Middle is the intermediate window. this window shows intermediate info about the code in the text-editor. It helps to estimate latency and can be
focused on a selection (as seen in the model).
-Below is the main menu:
-Save -> Save current file
-Lock -> Lock selection to protect it from accidental changes
-Emulate -> Not sure how this is going to work exactly, but am planning on making a simple emulator that can run selected pieces of code and collect info about the execution
-Stat-mode -> Specifies what you are looking at in the window below
-Options -> Will switch the screen to an extra options menu where preferences and display options are stored
-Help -> Usage documentation
-Below that is a statistics diagram, I imagine it displaying some sort of latency diagram generated from debug-information that corresponds with the current selection of code.
-Window top right is the hex view of the binary produced by the code, this will give you a look at what the binary is going to look like. Much like the intermediate window
this hex-editor will update everytime the code changes. This process will also work vice-versa, meaning any changes within the hex editor will update the code/selection.
-Pretty self explanatory except the whole record stuff. Basically this is where you select debug-records to save or load them on top of the current file.
Pretty far fetched, still. But I had a lot of fun creating that image and I hope some day in the future I will actually be able to use this, maybe even a more advanced version.
Even tho a lot was implied about how using high-level languages is the better and safer way I have not given up on my idea of further diving into the world of pure ASM. Already having mentioned some of my main concepts for the IDE I have been wanting to implement I have made a small mock-up image that roughly outlines what I had in mind on what it will look like. You can take a look at it and tell me what you think. A small description of what you are looking at:
-Window top left is the code editor, self-explanatory
-Below something that looks like something out of an instant-messenger, its a smaller text input that automatically formats and inserts the code in
a customize-able pattern.
-Next to it: a small intermediate info on what you are writing/what is selected.
-The ? is a helpful link to a documentation that you can pop-up on any instruction to find data about the particular instruction you want to use
-Middle is the intermediate window. this window shows intermediate info about the code in the text-editor. It helps to estimate latency and can be
focused on a selection (as seen in the model).
-Below is the main menu:
-Save -> Save current file
-Lock -> Lock selection to protect it from accidental changes
-Emulate -> Not sure how this is going to work exactly, but am planning on making a simple emulator that can run selected pieces of code and collect info about the execution
-Stat-mode -> Specifies what you are looking at in the window below
-Options -> Will switch the screen to an extra options menu where preferences and display options are stored
-Help -> Usage documentation
-Below that is a statistics diagram, I imagine it displaying some sort of latency diagram generated from debug-information that corresponds with the current selection of code.
-Window top right is the hex view of the binary produced by the code, this will give you a look at what the binary is going to look like. Much like the intermediate window
this hex-editor will update everytime the code changes. This process will also work vice-versa, meaning any changes within the hex editor will update the code/selection.
-Pretty self explanatory except the whole record stuff. Basically this is where you select debug-records to save or load them on top of the current file.
Pretty far fetched, still. But I had a lot of fun creating that image and I hope some day in the future I will actually be able to use this, maybe even a more advanced version.
Re: my idea
Maybe I could write one OS like that with a text editor and an assembler, (joking)
Ideas :
Make 2 Kernels, The first one would be called Developer Kernel and the second User Kernel
The User Kernel will be editable through the developer Kernel.
The Developer Kernel would consist of an assembler, and an IDE.
The assembler will have an option like : Compile to User Kernel, where the assembler would assemble the code, and the replace the assembled code with the User Kernel Binary.
The User will have an option to Choose to boot which kernel either the User or the Dev Kernel, Using GRUB or whatever bootloader.
The toughest part would be writing the assembler, maybe we could port an existing one like FASM, FASM is easily portable...
I like the idea, it has the following advantages :
If the OS lacks something like Networking or any other feature, an experienced programmer would be able to write a Network Driver on the OS itself, so if he/she wants a certain feature they would code it themselves,also he/she wouldn't require a Virtual Machine or any other Development Computer.
The idea reminds me of Linus Torvalds, in a meeting he said that he wrote everything himself the compiler, the OS , the IDE etc.
Btw which image editor did you use to make that?
Ideas :
Make 2 Kernels, The first one would be called Developer Kernel and the second User Kernel
The User Kernel will be editable through the developer Kernel.
The Developer Kernel would consist of an assembler, and an IDE.
The assembler will have an option like : Compile to User Kernel, where the assembler would assemble the code, and the replace the assembled code with the User Kernel Binary.
The User will have an option to Choose to boot which kernel either the User or the Dev Kernel, Using GRUB or whatever bootloader.
The toughest part would be writing the assembler, maybe we could port an existing one like FASM, FASM is easily portable...
I like the idea, it has the following advantages :
If the OS lacks something like Networking or any other feature, an experienced programmer would be able to write a Network Driver on the OS itself, so if he/she wants a certain feature they would code it themselves,also he/she wouldn't require a Virtual Machine or any other Development Computer.
The idea reminds me of Linus Torvalds, in a meeting he said that he wrote everything himself the compiler, the OS , the IDE etc.
No, it isn't. If you are a good coder and you believe in yourself nothing can stop you.EdTheClown wrote:Pretty Far-Fetched........
Btw which image editor did you use to make that?
When you say, "I wrote a program that crashed Windows," people just stare at you blankly and say, "Hey, I got those with the system, for free." - Linus Torvalds
64 bit Kernel in early development
http://github.com/nerdguy12/core64
64 bit Kernel in early development
http://github.com/nerdguy12/core64
Re: my idea
Hi everyone,
I'm a long time lurker, first time poster.
And to be honest my coding skills are nowhere near the level of you chaps. I gave up on ASM around the age of 17 and that was a loooong time ago.
These days I work way up the abstraction path in .NET land, but still enjoy cracking open the hood from time to time seeing what I can break down the stack.
Ed's o.p reminding me of a project I was tinkering with a while back. I stumbled across a virtual machine called B32 that was an example doing this is C#.
For some reason my brain went "if you can emulate an abstract machine you should be able to emulate ANY abstract machine"; so I started work on In Principio.
The idea of In Principio was to allow the user to create a simple processor architecture consisting of a memory model and registers; then define instructions and implement them in C#. Once the virtual processor was created the user could write ASM programs using an in-built editor; then have I.P assemble a binary image, boot the VM and run the code.
Random screen grab below.
I have no idea who would ever want to use this
Didn't take it beyond a pretty buggy alpha, mostly because, well summer came along and outside is nice.
The point of all this is just to say; Ed....your idea, not so crazy that other people don't wonder about similar things.
[edit]
Forgot to mention that when I was working on this I shamelessly stole knowledge from osDev, so you all need a credit
I'm a long time lurker, first time poster.
And to be honest my coding skills are nowhere near the level of you chaps. I gave up on ASM around the age of 17 and that was a loooong time ago.
These days I work way up the abstraction path in .NET land, but still enjoy cracking open the hood from time to time seeing what I can break down the stack.
Ed's o.p reminding me of a project I was tinkering with a while back. I stumbled across a virtual machine called B32 that was an example doing this is C#.
For some reason my brain went "if you can emulate an abstract machine you should be able to emulate ANY abstract machine"; so I started work on In Principio.
The idea of In Principio was to allow the user to create a simple processor architecture consisting of a memory model and registers; then define instructions and implement them in C#. Once the virtual processor was created the user could write ASM programs using an in-built editor; then have I.P assemble a binary image, boot the VM and run the code.
Random screen grab below.
I have no idea who would ever want to use this
Didn't take it beyond a pretty buggy alpha, mostly because, well summer came along and outside is nice.
The point of all this is just to say; Ed....your idea, not so crazy that other people don't wonder about similar things.
[edit]
Forgot to mention that when I was working on this I shamelessly stole knowledge from osDev, so you all need a credit
-
- Posts: 4
- Joined: Tue Oct 29, 2013 3:54 am
Re: my idea
Hello again!
Thanks for all the inspiring posts that have been contributed! I loved reading them.
I hope you don't mind me digging this thread back up, I have some new stuff to "share".
First tho i'd like to say that I really like your idea nerdguy, but what I was thinking was more
along the lines of a really decentralized OS that starts of as loose as possible so everyone can pretty
much develop his own architecture on top. Was thinking I was going to make mine into a completely
service based architecture, as in small background programs that can be turned on and off. But again,
I am not looking to provide an architecture but rather a small start-up initialization and the proper tools
to have the architecting-fun on your own.
Now I'd like to bring some attention to a open-source project that I found on the webs. For my interpreter
(or whatever you want to call it) I would need some sort of latency-record for the range of CPU models
people would be likely to work with, something that holds all the information about what instruction takes
how long. And I actually found a program that provides exactly that kind of information and packages it
neatly into an XML file. The project is called "mubench" and was licensed by Alex Izvorski, you can find it
at http://mubench.sourceforge.net/.
I am eternally grateful that I didn't have to come up with this myself, as it demands a pretty in-depth knowledge
of CPUs in general to build something like this from what it seems. So I was hoping I could give something back
by posting my generated latency-record of my i7 on their sourceforge page.
Maybe some of you guys are interested and would like to contribute your latency-records too? Pretty sure the creators
would appreciate it alot and it only takes a few minutes to generate.
Thanks for all the inspiring posts that have been contributed! I loved reading them.
I hope you don't mind me digging this thread back up, I have some new stuff to "share".
First tho i'd like to say that I really like your idea nerdguy, but what I was thinking was more
along the lines of a really decentralized OS that starts of as loose as possible so everyone can pretty
much develop his own architecture on top. Was thinking I was going to make mine into a completely
service based architecture, as in small background programs that can be turned on and off. But again,
I am not looking to provide an architecture but rather a small start-up initialization and the proper tools
to have the architecting-fun on your own.
Now I'd like to bring some attention to a open-source project that I found on the webs. For my interpreter
(or whatever you want to call it) I would need some sort of latency-record for the range of CPU models
people would be likely to work with, something that holds all the information about what instruction takes
how long. And I actually found a program that provides exactly that kind of information and packages it
neatly into an XML file. The project is called "mubench" and was licensed by Alex Izvorski, you can find it
at http://mubench.sourceforge.net/.
I am eternally grateful that I didn't have to come up with this myself, as it demands a pretty in-depth knowledge
of CPUs in general to build something like this from what it seems. So I was hoping I could give something back
by posting my generated latency-record of my i7 on their sourceforge page.
Maybe some of you guys are interested and would like to contribute your latency-records too? Pretty sure the creators
would appreciate it alot and it only takes a few minutes to generate.