flat assembler
Message board for the users of flat assembler.

Index > Main > writing assembler

Author
Thread Post new topic Reply to topic
b1528932



Joined: 21 May 2010
Posts: 287
b1528932 01 Nov 2010, 17:45
There are many cpus. those cpus can support many instruction encoding, depending on mode in wich they are.

Is there a way to create nuiversal assembler, wich would have distinct mnemonics delepding on actual state of cpu?


For example, x86_64 can support real/protected and long mode. Each of those modes has diffrent instruction sets (same a sequence of bytes to diffrent stuff).

Is it worth creating instructions like 'shr eax,4', 'mov eax,[0]', etc?

And there is 1 more problem, some instructions may be encoded in difrent ways, for example inc/dec, mov r64,[offset]/mov r64,[modrm].

cpus will be more and more complex, and its possible that they will add so many modes, that you would have to write few hundres words describing it (cpu type, mode 1, state of msrA, state of msrB, state of other things).

So how to create something that is universal, language with 1 to 1 translation into cpu code?
Post 01 Nov 2010, 17:45
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 01 Nov 2010, 23:42
C-- was created with a goal similar to this. I never learned it, and know little of the extent of it's success at being a processor independent very low level language.
Post 01 Nov 2010, 23:42
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 02 Nov 2010, 00:00
b1528932 wrote:
So how to create something that is universal, language with 1 to 1 translation into cpu code?
We already have this:
Code:
db 0x??, 0x??, ...    
If you try to do anything else then you will strike problems. eg. what is the binary for this line?
Code:
add eax,ebx    
There are two ways to encode this, and each way is equally valid. It would look kind of ugly (and unnecessary) to do something like this:
Code:
add reg.eax,modrm.ebx ;version 1
add modrm.eax,reg.ebx ;version 2    
Post 02 Nov 2010, 00:00
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4353
Location: Now
edfed 02 Nov 2010, 01:02
i understand the question as i ask it to myself some times.

one way to let a CPU interpret a sort of universal code can be resolved if you find the way to do the more little basic function set that lets you create a virtual turing complete machine.

then, X86, 68k, etc will be able to execute the same "bytecode" as is, without modifications or adaptation.

some company resolved that with JAVA.

try first to implement a very simple
add, sub, neg, not, xor, and, or, cmp, jmp, jcc, mov, mul, div, shr, shl, sar... brieflly, implement a reduced instruction set (and some adressing modes)
and you will have your turing complete machine, ready to work on any cpu.
Post 02 Nov 2010, 01:02
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 02 Nov 2010, 04:11
b1528932 wrote:
So how to create something that is universal, language with 1 to 1 translation into cpu code?
This is very important from an optimization standpoint. It would be nice to have an assembler which allowed selection of encoding (i.e. right-click and select method through some meta-data tag). Presently, we are required to DB $??,$??,... which is not flexible enough to try different permutations (i.e. almost no one bothers). Code alignment, reduced decode pressure, ... would benefit from such features.

I've been calling it a fragmentation assembler for several years. It would know every intimate detail about the target machines, and could display advanced information about how the code would execute (on average, or specific (entry/exit analysis)). Assembly happens in real-time because editors don't really use cycles. Of course, it would only be compatible with assembler / linker / loader through export.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 02 Nov 2010, 04:11
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 02 Nov 2010, 04:16
Perhaps use a three byte operand type:
Code:
add eax,eax,ebx ;'d' bit = 0
add eax,ebx,eax ;'d' bit = 1    
Or specify the 'd' bit directly:
Code:
add.0 eax,ebx
add.1 eax,ebx    
Post 02 Nov 2010, 04:16
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4073
Location: vpcmpistri
bitRAKE 02 Nov 2010, 05:56
But if the flags aren't needed then LEA EAX,[EAX+EBX] could offer different use of processor resources. The assembler could know this based on following instructions. My premise is that optimization would benefit from greater presentation during coding - compartmentalizing the complexity (NP-Hard) - instead of working across several tools in parallel, or making many assumptions.

Abstracting syntax just moves the problem around without offering greater visibility. What is needed at a particular code point can change dynamically based on surrounding instructions and required outcome. We've seen from the challenges here how complex only a few instructions can be.

I've imagined a project like GMP could benefit from such an assembler.
(Look at the superoptimizer presently used.)
Post 02 Nov 2010, 05:56
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4353
Location: Now
edfed 02 Nov 2010, 12:31
a generic asm don't know what mov is.
it uses accumulator to store the immediatelly accessible data.

on pic, it is the W register.
on 68hc11, it is the Accumulator register

many CPU (and MCU) have a designed hardware to comply with different ways to compute the same thing.

then, it leads to a problem; how to efficientlly encode this type of mnemonic?:
Code:
inst op1,op2  ; op1 & op2 are optional and needs inst to be defined
    


assuming a machine (virtual or not) will provide mechanisms to accelerate some desired things, like the MAC instruction in 68HC16, or the register bank ram in PICs, we need to define a common squeleton in order to make the better and lighter code.

that is a big problem because if we use a generic instruction set, it means we will be unable to use specific instruction set, or we will need a set of fucntions, that will execute code as native but will be virtualy compatible with the generic instructions set.

the very reduced instruction set would look like this one: (i think)



; A is the accumulator, located in all register banks
; B is the register Bank selector, located in all register banks
; basically, all internal CPU registers will be in all register banks.
; a register bank is 256 bytes
; the 16 first positions of all banks store all 16 CPU registers.
; all registers are 8bits
; the first byte of any instructioin is the mnemonic
; the second byte is op1
; the third byte is op2
; the adressing Mode is set by a CPU register named M and located in register bank
; the Mode register will encode many ways to interpret instructions.
; the IP register is in register bank and covers 256 bytes
; the IP register is relative to C register, the code register will point to a bank in a 256 banks array.
a 256 banks array means 65536 bytes of memory for code
and 65536 byte for datas
; the B register is for register Bank
; the C register is for Code bank
; the D register is for Data bank
;
;to execute complex code, there will be a very huge overhead, but it will be portable
; means portability is slow and memory bloat.

; all registers in register banks can be modified via STA instruction
; the jump instructions will add an offset to current ip accordinglly to the result in F register (in register bank)
; the call instruction will set the current ip
; the ret instruciton will restore ip
;

Code:

lda op1 ;op1 is a register in 256 register Bank, indexed by B register
sta op1

stb op1 
ldb op1 
lds op1


and op1,op2
or op1,op2
xor op1,op2

add op1,op2

save op1
restore op1


jz op1
jc op1
js op1
jp op1

;many other risc instructions to define (up to 256 in total)

    
Post 02 Nov 2010, 12:31
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


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


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.