Calling C/Asm from Espruino...

Posted on
  • Is now a reality! (As of 1v60, or git commit a92ea2e529588c6f86cf268ff227438167052843­)

    addr = process.memory().stackEndAddress;
    
    [0xb480,0xb083,0xaf00,0x6078,
     0x687b,0xf103,0x0302,0x4618,
     0xf107,0x070c,0x46bd,0xbc80,
     0x4770,0xbf00].forEach(function(v,a) { poke16(addr+a*2,v); });
    a = E.nativeCall(addr+1, "long (long)");
    

    The code above is just copy/pasted out of an object file generated by GCC. It takes a 64 bit int and adds 2 to it.

    The function a that got created can be used just like any normal function:

    >a(0) 
    =2
    >[1,2,3,4].map(a)
    =[3,4,5,6]
    

    So who wants to make a Thumb assembler written in JavaScript? :) Could be a fun project...

    I actually got TCC (the Tiny C compiler) compiled into JavaScript with Emscriptem (so it could have run on the Web IDE), but unfortunately I can't get the code it produces to run on the Cortex M3.

  • Thumb opcodes here: https://ece.uwaterloo.ca/~ece222/ARM/ARM­7-TDMI-manual-pt3.pdf - it should be pretty easy to make an assembler from that...

  • Super hacky assembler here: https://gist.github.com/gfwilliams/99588­15
    Doesn't do half what it's supposed to yet, but hopefully could be expanded and added to the Web IDE. I'm thinking something like detecting + replacing:

    var adder = E.asm("long(long)",
    "movs    r2, #2    "+
    "movs    r3, #0   "+
    "adds    r2, r2, r0"+
    "adc.w   r3, r3, r1"+
    "mov r0, r2        "+
    "mov r1, r3        "+
    "bx  lr            ");
    
  • And it's done. With the latest Web IDE and Espruino from GitHub, you can now do inline assembler:

    var adder = E.asm("long(long)",
    "movs    r2, #3",
    "movs    r3, #0",
    "adds    r2, r2, r0",
    "adc.w   r3, r3, r1",
    "mov r0, r2",
    "mov r1, r3",
    "bx  lr");
    ...
    >adder(2)
    =3
    

    Looks like nobody is as excited about this as me :(

    The assembler is here: https://github.com/espruino/EspruinoWebI­DE/blob/master/js/plugins/assembler.js

    It still needs a huge amount of work in order to support a usable amount of Thumb2, but it seems promising. Perhaps there's already an assembler that could be used?

    I think for fast IO this could be extremely useful - for instance the LED displays mentioned here could have a bit of assembler that bit-bashed each byte.

  • Awesome! I like it very much! It's very useful : )

  • It's an interesting balancing act supporting a high level language on one side and assembler on the other one.
    Just downloaded Web IDE, but I'm unsure about nightly build. Last nightly build is much smaller for last 4 versions and tests.log is empty since yesterday 1:14 pm. Is latest built best choice ?
    Last time I did something in assembler is long long ago, the time of Z80, 6502 and last one 68000. Lets see what ARM assembler is at the end, confusing like Intel or structured like Motorola.

  • Hi Gordon,

    It's interessting to me too. Last time i used assembler is also a long time ago, 68000. Maybe we can use it to write modules? Not to speed up things but for saving memory.

    I wonder how we have to access PIN's or UARTs/SPI in assembler.
    Or even in C/C++ ?

    Sacha

  • Best to use the proper 1v60 release (just made it). The recent one was smaller because I changed the compile flags, but it seemed to make the build unreliable so I've changed it back :(

    I'll have to try and do some examples of accessing pins - it's just a matter of accessing an address that's found in the STM32F103 reference manual.

    Including C code would be awesome. There's a compiler called TCC which supposedly supports ARM, and which I managed to compile to JavaScript with Emscripten. Sadly the ARM code it generates doesn't seem to run. It might do with some fiddling though - in which case you'd just be able to write inline C :)

  • Old timer like me used to use assemblers for many years, then switched to high level languages just to simplyfy things (MCU are very powerfull so you do not to count CPU cycles now). Of course interpreters can consume a lot of processing power. I guess Gordon wants to integrate the assembler functionality to speed up things when needed...

    I personally use arduino or javascript in this case just to hide complexity related to MCU peripherals (to avoid reading manuals each time I switch from one MCU to another). I guess many people do the same for this reason.

  • I wonder what you think about new possibilities related to this feature....

  • Yes, I fully imagine that virtually everyone will use JavaScript. However at least it is now possible to do things very quickly where it is needed :)

  • More details on inline assembler here: http://www.espruino.com/Assembler

  • Excellent! I'm excited, I just missed the thread! (btw, I thought I told the forum I was interested in new posts, which it seems to ignore!). As you correctly say, it's nice to know you can do fast things if you have to!

  • afaik the forum only tells you about one new post per forum - so if you see one e-mail and then don't check the forum, you won't get any other e-mails. It always keeps tripping me up :)

  • I've been working with the assembler, but it seems some of the opcodes I have tried to use are missing. This said I'm not sure if they are all supported, but looking at the specs for the STM32F103RCT6 and following the link for the Cortex™-M3 Technical
    Reference Manual
    it seems a bit more than what is currently implemented should work (but doesn't).

    For example 'subs' should work or shouldn't it?

    Is there a reason for this or does any list exists about what works and what doesn't?

    And for the existing code is there a unit test to check whether the code produces correct output?

  • I guess I should look at the documentation more properly: It's stated clear that only the Thumb-Opcodes are supported and not the Thumb-2 opcodes (except a few, which made me think that they were supported all together).

    I've now downloaded the ARMv7m manual and checking the opcodes. Eventually I can improve the assembler to support more of the Thumb-2 instructions...

  • That's be great - thanks!

    In the mean time you could assemble it on your PC and then use https://www.espruino.com/File+Converter to convert that for Espruino, which you could then use with E.nativeCall as the Assembler does?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Calling C/Asm from Espruino...

Posted by Avatar for Gordon @Gordon

Actions