help ...asm language for esp8266

Hi!

I make some tests with arduino ide. The pointers,Strings,Integers,Chars is a "black hole" for me ... i try

to understand , with little step at atime ... but i see that is a long way for understand!

So...long,long time ago ... i begin with asm and after with bascom ... and after and after ... arrived at esp8266

and many ide is in c language and any ide with your characteristics!

So ... my question is ... How can made for access a memory point address (but fizic address like 0x2345678) and after is my job to interpret location at char, int or anyelse.

For example in avr , to read with asm a byte

ldi ZH, high(Table_1<<1) ; Initialize Z pointer
ldi ZL, low(Table_1<<1)
lpm r16, Z ; Load constant from program
; memory pointed to by Z (r31:r30)

So put in register Z adress

and loaded value of location memory in register

example :

If at address 12345678 i have 65

This mean at :

integer that is low byte (at 12345679 is high byte... and long is 4 byte... ecc)

byte is 65

char is "A"(and if is char test[10]; i so that at adress 12345678+10+1 have "\0")

ang go on...

i thing that is much simple in this mode

Example for ... next :

In arduino :

for(i=0; i<100; i++)
{
    //Do something
}

in advanced asm:

ldi r16,100

loop:
; Do something
dec r16
brne loop

Where can find this?

After 4 years ... today 05.11.2022 finally i find the problem !!!
The xtensa-lx106-elf-g++.exe and another executables from package not functioning alone ... i think that have dependencies inside package .
So if download package
https://dl.espressif.com/dl/xtensa-lx106-elf-gcc8_4_0-esp-2020r3-win32.zip
from here
https://docs.espressif.com/projects/esp8266-rtos-sdk/en/latest/get-started/windows-setup.html
and put folder xtensa-lx106-elf in C:
C:\xtensa-lx106-elf\bin\xtensa-lx106-elf-g++.exe -Wall -O2 -ffreestanding -c main.cpp -o main.o
working!!!

main.cpp
void setup();
void loop();
void setup() {
asm(" movi.n a5, 100");
}
void loop() {
asm(" movi.n a4, 120");
}

Hello costy35

Is that what you are looking for ?

Regards,
bidouilleelec

:o
Yes i see before! :o is huuuge!

But how implement ... some small examples!

Until now i not find anything ... or i find some examples , but is hard to understand!

A little example with how find address of variable and how load this value!

Anyway ... bidouilleelec ...thanks for quick response!

The whole point of higher-level languages like C/C++ is that you don't have to worry about specific implementation details such as addresses.
Everything you've written can easily be done in C in a much cleaner, compact, and robust way. The compiler lays out the memory for you, and calculates the addresses accordingly.

IMHO, unless you want to write your own ESP8266 compiler, or another very specific, high-performance application, learning its ASM is a total waste of time.

Pieter

Hello costy15

costy35:
But how implement ... some small examples!

Until now i not find anything ... or i find some examples , but is hard to understand!

A little example with how find address of variable and how load this value!

One way is to write simple examples and disassemble them , playing with the compiler/optimizer options.

Regards,
bidouilleelec

How?

A long time ago with arduino ,bascom ... ecc ... for see how compiler compile my command...

put a lines with for examples

ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
my line code 
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0
ldi r16,0

in this way i can see in huge strings of asm lines ... my function

but how can find the asm file at arduino esp8266 compiler?

Now i remember that not used ldi r16,0 ...
i used 'nop '

Hello costy35

costy35:
How?

One way is to write simple examples and disassemble them , playing with the compiler/optimizer options.

I wanted to write :
One way is to write simple examples in C/C++ and disassemble them , playing with the compiler/optimizer options, to see what the compiler does.

Regards,
bidouillelec

Hello PeterP

PieterP:
IMHO, unless ....., learning its ASM is a total waste of time.

Pieter

AMHA, it's the only way to understand accurately how your Arduino (or else) works.

Regards,
bidouilleelec

I thing that asm is in temp folder ... but where?
I try on internet but i not find a good response.

I find elf file ... that is responsable with asm code (in temp folder)
But not see asm files ...

  X10
    –   €   €      48<@ $(,0x   ÿ   n   À À           2.2.1(cfd48f3)      d   @ Ýa Pò                                     û!ù?û!	@|Ù@û!@zj@|Ù"@»ý%@û!)@:F,@zj/@\G1@|Ù2@œk4@»ý5@ۏ7@û!9@e´:@:F<@ZØ=@zj?@L~@@\GA@lB@|ÙB@Œ¢C@œkD@¬4E@»ýE@ËÆF@ۏG@ëXH@û!I@ƒù¢ DNn ü) ÑW' Ý4õ bÛÀ <™• AC cQþ »Þ« ·aÅ :n$ ÒMB Ià 	ê. ’Ñ ëþ )± è>§ õ5‚ D». œé„ ´&p A~_ Ö‘9 Sƒ9 œô9 ‹_„ (ù½ ø; Þÿ— ˜ /ï 
Z‹ mm Ï~6 	Ë' FO· žf? -ê_ º'u åëÇ ={ñ ÷9a ’RŠ ûkê ±_ ] 0V {üF ð«k  ¼Ï 6ôš ã© ^a‘ eæ …™e  _ @h €Øÿ 'sM 1 ÊV ɨs {â` kŒÀ    @û!ù?    -Dt>   €˜Fø<   `QÌx;   €ƒeð9   @ %z8   €"‚ã6    ói5            âe/"+z<a\3&¦<½Ëðzˆap<a\3&¦‘<O»ag¬Ý?-DTû!é?›öÒsï?-DTû!ù?ƒþ?    Z!@h!@a!@€!@ˆ!@h!@Z!@4   ÎûÿÿË         5   ÎûÿÿË             ¼‰Ø—²Òœ<3§¨Õ#öI9=§ôDý¥2—ŒÏº[%Co¬d(h          (((((                  ˆAAAAAABBBBBB                                                                                                                                                                                                                                              }       ¼‰Ø—²Òœ<3§¨Õ#öI9=§ôDý¥2—ŒÏº[%Co¬d(È
 €à7yÃACnµµ¸“Fõù?éO8M20ùHw‚Z<¿sÝOu      ð?      $@      Y@     @@     ˆÃ@     jø@    €„.A    ÐcA    „×—A    eÍÍA    _ B   èvH7B   ¢”mB  @åœ0¢B  Ä¼ÖB  4&õkC €à7yÃAC  Ø…W4vC ÈNgmÁ«C =‘`äXáC@Œµx¯DPïâÖäKD’ÕMÏð€DöJáÇ-µD´ÙyCxêD       Abla bla bla text/html   G01 X1.27 Y2.00 <div><svg height='210' width='500'><line x1='0' y1='0' x2=' ' y2='  ' style='stroke:rgb(255,0,0);stroke-width:2' />Sorry, your browser does not support inline SVG.</svg></div> <h1> X step/mm= </h1>   <h1> Y step/mm= <h1> Feedrate=  
    <h1><form action='http://192.168.4.1/arguments'>    Feedrate: <input type='text' name='feedrate' value= >
   X step/mm: <input type='text' name='stepx' value=   Y step/mm: <input type='text' name='stepy' value=   <input type='submit' value='Set parameters'>    </form></h1>    <script>location.replace('http://192.168.4.1/potracex')</script>    Feedback    Feedback Argument not found Feedback Argument =     <h1>    feedrate    feedrate =  stepx   stepx =     stepy   stepy =     <p>go to <a href='http://192.168.4.1'>index</a></p></h1>    asolute=    
<p>go to <a href='http://192.168.4.1'>index</a></p> .html   .css    text/css    .js application/javascript  .ico    image/x-icon    .gz application/x-gzip  text/plain  delta_units.x=    delta_units.y=    acum sunt in process_string ok  huh? G  Huh? M  Again-> <p><a href='http://192.168.4.1/grbl'>http://192.168.4.1/grbl</a></p>    costycnc    Gcode1 =    <textarea rows='4' cols='50' name='textg'>  </textarea> <div><svg height='500' width='500'><g transform='scale(10)'><polyline stroke='black' fill='none' stroke-width:.1 points='   ' />Sorry, your browser does not support inline SVG.</g></svg></div>    <html><head><script>document.body.innerHTML = '<html></html>';</script></head><body><div><textarea> </textarea></div>   <progress value='   ' max='85'></progress></body></html>    0   test=   =sfarsit    ,   Access-Control-Allow-Origin *   handleFileRead:     /   index.html  r   	Sent file:     	File Not Found:    /upload.html    404: Not Found  <!DOCTYPE html><html><head><script>document.body.innerHTML ='';</script></head><body><svg height='180' width='500'> <g transform='scale(10)'><polyline points=' ' style='fill:white;stroke:red;stroke-width:.1' />  Sorry, your browser does not support inline SVG.</svg></body></html>    /test.nc    G01     file open failed    ====== Reading from SPIFFS file ======= <h1>====== Reading from SPIFFS file =======</h1>     <p>You need wait until cnc finished moving</p> go to index -><a href='http://192.168.4.1/index.html'>http://192.168.4.1/index.html</a></p> <html><head>    <script>document.body.innerHTML = '';</script></head><body><h1>====== Reading from SPIFFS file =======</h1> go to index -><a href='http://192.168.4.1/index.html'>http://192.168.4.1/index.html</a></p></body></html>   <svg xmlns='http://www.w3.org/2000/svg' version='1.1'   width='250' height='250'><rect x='25' y='25' width='200'    height='200' fill='lime' stroke-width='4' stroke='pink'></rect></svg></html>     /  
  handleFileUpload Name:  w   handleFileUpload Size:  500: couldn't create file   Costycnc    TCP server started  /upload /costycnc   /grbl   /test   /blink  /fileread   /list   /svg    /potracex   /arguments  /absolute   /string /rssi   /header /costel HTTP server started <!DOCTYPE html><html><head><title>CaptivePortal</title></head><body><h1>Hello World!</h1><p>This is a captive portal example. All requests will be redirected here.</p></body></html>   _pos + size <= _size    buffer == _data + _pos  pcb == _pcb _connect_pending    cb == size  _datasource == nullptr  _send_waiting == 0  const uint8_t* BufferedStreamDataSource<TStream>::get_buffer(size_t) [with TStream = Stream; uint8_t = unsigned char; size_t = unsigned int]    const uint8_t* BufferedStreamDataSource<TStream>::get_buffer(size_t) [with TStream = ProgmemStream; uint8_t = unsigned char; size_t = unsigned int] size_t ClientContext::_write_from_source(DataSource*)   err_t ClientContext::_connected(tcp_pcb*, err_t)    virtual void BufferDataSource::release_buffer(const uint8_t*, size_t)   virtual const uint8_t* BufferDataSource::get_buffer(size_t) %08x    %x%s    %s:%s   index.htm   Cache-Control   0x00    --  "   Host    :%d     
Exception (%d):
epc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x
   
ctx: sys 
 sp: %08x end: %08x offset: %04x
    %08x:  %08x %08x %08x %08x %c
  C:\Users\costycnc\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\abi.cpp   __throw_bad_function_call   __cxa_pure_virtual  C:\Users\costycnc\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\core_esp8266_main.cpp 2_4_1   loop_task   __yield                @               €    nan inf ovf .   C:\Users\costycnc\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\cores\esp8266\spiffs_api.h  name    close   _getStat    size    position    seek    flush   read    write   MD5 Failed: expected:%s, calculated:%s
 0123456789abcdef    %s %u

is another mode to obtain elf with asm code?

Take a look at Compiler Explorer. You should be able to install the ESP8266 XTensa compiler, and it will be much easier to use.

You want to run the ....-objdump utility that sits in the tools binary directory. Probably on individual .o file, since a fully compiled esp sketch runs to 200k+ of code.

Assuming that “int n = (int)(0x2345678);”
Is not good enough. Iirc the flash may only be accessible as 32bit words, for certain sections.

The tensilica cpu used seems to have rather poor documentation, compared to what we’re used to getting out of Atmel. And ugly instruction names

So ... i succeeded read asm about arduino compiler ... is hudge file, but for some experiments is good a begin!

So ... i compile blink example from arduino examples ! Is not important that 13 is not compatible with esp,

i only want what happen with file.

void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

and i dont know until now that can compile esp only inserting the esp8266com from new folder

"hardware" created in my documents/Arduino

So ... i insert esp8266com from here [https://github.com/Yveaux/esp8266-Arduino](https://github.com/Yveaux/esp8266-
Arduino)

and i set on Arduino in File/Preferences Show verbose output during compilation

and after compile i can see directory where arduino ide have temporary file for extract elf file

So ... elf file copy to my documents. elf file is hudge for few lines of codes ... have 900kb!!!!

Copy objdump.exe in My Documents from

My Documents\Arduino\hardware\esp8266com\tools\windows\xtensa-lx106-elf\xtensa-lx106-elf\bin\objdump.exe

Create a batch file ( my elf file is blink.elf)

@echo off 
cls

objdump -S blink.elf > blink.txt
pause

and save in My Documents with name decompile

Now in My Documents i have decompile.bat,objdump.exe and blink.elf ...

So when execute decompile.bat result a huge file for about 4MEGA !!!! that contains asm codes!

I so that somewhere already exists these informations ... but when these informations is in many place

is also easy to find.

Also is good for me when forget how obtain asm from arduino esp8266 ...

And put here costycnc name for to be easy to find when type costycnc esp8266 in google !

Here is head , a few lines begin from asm file for blink.ino

blink.elf:     file format elf32-xtensa-le


Disassembly of section .irom0.text:

40201010 <core_version>:
40201010: 32 7c 4f 61                                         2|Oa

40201014 <delay_end>:
static uint32_t micros_at_last_overflow_tick = 0;
static uint32_t micros_overflow_count = 0;
#define ONCE 0
#define REPEAT 1

void delay_end(void* arg) {
40201014: f0c112         addi a1, a1, -16
40201017: 3109       s32i.n a0, a1, 12
    (void) arg;
    esp_schedule();
40201019: 00aac5         call0 40201ac8 <esp_schedule>
}
4020101c: 3108       l32i.n a0, a1, 12
4020101e: 10c112         addi a1, a1, 16
40201021: f00d       ret.n
40201023: e6dc00         excw
40201026: fe           .byte 0xfe
40201027: 3f           .byte 0x3f
40201028: e6d8       l32i.n a13, a6, 56
4020102a: fe           .byte 0xfe
4020102b: 3f           .byte 0x3f
4020102c: 1013b0         and a1, a3, a11
4020102f: c11240         mul16u a1, a2, a4

40201030 <micros_overflow_tick>:
    if(ms) {
        os_timer_disarm(&delay_timer);
    }
}

void micros_overflow_tick(void* arg) {
40201030: f0c112         addi a1, a1, -16
40201033: 036102         s32i a0, a1, 12
    (void) arg;
    uint32_t m = system_get_time();
40201036: fffd01         l32r a0, 4020102c <delay_end+0x18>
40201039: 0000c0         callx0 a0
    if(m < micros_at_last_overflow_tick)
4020103c: fffa31         l32r a3, 40201024 <delay_end+0x10>
4020103f: 0358       l32i.n a5, a3, 0
40201041: 034d       mov.n a4, a3
40201043: 09b257         bgeu a2, a5, 40201050 <micros_overflow_tick+0x20>
        ++micros_overflow_count;
40201046: fff831         l32r a3, 40201028 <delay_end+0x14>
40201049: 0358       l32i.n a5, a3, 0
4020104b: 551b       addi.n a5, a5, 1
4020104d: 006352         s32i a5, a3, 0
    micros_at_last_overflow_tick = m;
}
40201050: 3108       l32i.n a0, a1, 12
void micros_overflow_tick(void* arg) {
    (void) arg;
    uint32_t m = system_get_time();
    if(m < micros_at_last_overflow_tick)
        ++micros_overflow_count;
    micros_at_last_overflow_tick = m;
40201052: 0429       s32i.n a2, a4, 0
}
40201054: 10c112         addi a1, a1, 16
40201057: f00d       ret.n
40201059: 000000         ill
4020105c: fee6f4         excw
4020105f: 3f           .byte 0x3f
40201060: 201014         excw
40201063: 0e7440         excw
40201066: fc4010         excw
40201069: 0f           .byte 0xf
4020106a: 4c4010         excw
4020106d: 0f           .byte 0xf
4020106e: 124010         excw

40201070 <delay>:
void delay_end(void* arg) {
    (void) arg;
    esp_schedule();
}

void delay(unsigned long ms) {
40201070: f0c112         addi a1, a1, -16
40201073: 21c9       s32i.n a12, a1, 8
40201075: 3109       s32i.n a0, a1, 12
40201077: 11d9       s32i.n a13, a1, 4
40201079: 02cd       mov.n a12, a2
    if(ms) {
4020107b: 22ac       beqz.n a2, 402010a1 <delay+0x31>
        os_timer_setfn(&delay_timer, (os_timer_func_t*) &delay_end, 0);
4020107d: fff7d1         l32r a13, 4020105c <micros_overflow_tick+0x2c>
40201080: fff831         l32r a3, 40201060 <micros_overflow_tick+0x30>
40201083: 0d2d       mov.n a2, a13
40201085: 00a042         movi a4, 0
40201088: fff701         l32r a0, 40201064 <micros_overflow_tick+0x34>
4020108b: 0000c0         callx0 a0
        os_timer_arm(&delay_timer, ms, ONCE);
4020108e: 0d2d       mov.n a2, a13
40201090: 0c3d       mov.n a3, a12
40201092: 040c       movi.n a4, 0
40201094: 150c       movi.n a5, 1
40201096: fff401         l32r a0, 40201068 <micros_overflow_tick+0x38>
40201099: 0000c0         callx0 a0
4020109c: 000106         j 402010a4 <delay+0x34>
4020109f: 450000         extui a0, a0, 16, 5
    } else {
        esp_schedule();
402010a2: 4500a2         l8ui a10, a0, 69
    }
    esp_yield();
402010a5: 9f           .byte 0x9f
402010a6: 7c8c00         excw
    if(ms) {
        os_timer_disarm(&delay_timer);
402010a9: ffec21         l32r a2, 4020105c <micros_overflow_tick+0x2c>
402010ac: fff001         l32r a0, 4020106c <micros_overflow_tick+0x3c>
402010af: 0000c0         callx0 a0
    }
}
402010b2: 3108       l32i.n a0, a1, 12
402010b4: 21c8       l32i.n a12, a1, 8
402010b6: 11d8       l32i.n a13, a1, 4
402010b8: 10c112         addi a1, a1, 16

Im so happy! :slight_smile:

So when execute decompile.bat result a huge file for about 4MEGA !

Thus my suggestion to look at individual .o files. Jump/call target addresses may be wrong (they still need to be resolved by the linker, but the basic instruction layout should be OK.

You probably want to add the -C option to objdump as well, to get "de-mangeling" of C++ names.

Here's blink.o:

/Applications/Arduino-1.8.5.app/Contents/Java/portable/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/bin/xtensa-lx106-elf-objdump -SC sketch/Blink.ino.cpp.o

[color=brown][color=red]  [/color][/color]

sketch/Blink.ino.cpp.o:     file format elf32-xtensa-le
Disassembly of section .text.setup:

00000000 <setup-0x4>:
   0:   000000          ill
        ...

00000004 <setup>:
  http://www.arduino.cc/en/Tutorial/Blink */

// the setup function runs once when you press reset or power the board
void setup() {
   4:   f0c112          addi    a1, a1, -16
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
   7:   021c            movi.n  a2, 16
   9:   130c            movi.n  a3, 1
  http://www.arduino.cc/en/Tutorial/Blink */
// the setup function runs once when you press reset or power the board
void setup() {
   b:   036102          s32i    a0, a1, 12
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
   e:   fffc01          l32r    a0, 0 <setup-0x4>
  11:   0000c0          callx0  a0
}
  14:   3108            l32i.n  a0, a1, 12
  16:   10c112          addi    a1, a1, 16
  19:   f00d            ret.n

Disassembly of section .text.loop:
00000000 <loop-0x10>:
        ...
00000010 <loop>:

// the loop function runs over and over again forever
void loop() {
  10:   f0c112          addi    a1, a1, -16
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  13:   130c            movi.n  a3, 1
  15:   10a022          movi    a2, 16
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  18:   036102          s32i    a0, a1, 12
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  1b:   fff901          l32r    a0, 0 <loop-0x10>
  1e:   0000c0          callx0  a0
  delay(1000);                       // wait for a second
  21:   e8a322          movi    a2, 0x3e8
  24:   fff801          l32r    a0, 4 <loop-0xc>
  27:   0000c0          callx0  a0
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  2a:   021c            movi.n  a2, 16
  2c:   030c            movi.n  a3, 0
  2e:   fff601          l32r    a0, 8 <loop-0x8>
  31:   0000c0          callx0  a0
  delay(1000);                       // wait for a second
  34:   e8a322          movi    a2, 0x3e8
  37:   fff501          l32r    a0, c <loop-0x4>
  3a:   0000c0          callx0  a0
}
  3d:   3108            l32i.n  a0, a1, 12
  3f:   10c112          addi    a1, a1, 16
  42:   f00d            ret.n

costy35:
So ... i succeeded read asm about arduino compiler ... is hudge file, but for some experiments is good a begin!

I thought that you were speeking about esp8266.

As English is not my mother's tongue, I may have not understood you.

Regards,
bidouilleelec

There is an ESP8266 "board" add-on for Arduino that includes an "Arduino Compiler" which produces ESP8266 code.

There are "boards" that add compilers for ARM, MIPS (PIC32 - Chipkit), MSP430 (TI Launchpad), ESP8266, ESP32, ARC (Arduino/Intel 101), and x86 (Gallileo, Edison.) Perhaps more.

Hello westfw

westfw:
There is an ESP8266 "board" add-on for Arduino that includes an "Arduino Compiler" which produces ESP8266 code.

There are "boards" that add compilers for ARM, MIPS (PIC32 - Chipkit), MSP430 (TI Launchpad), ESP8266, ESP32, ARC (Arduino/Intel 101), and x86 (Gallileo, Edison.) Perhaps more.

As I'm only French :

What are you meaning by "boards" ?

Best Regards,
bidouileelec

The "board" menu of the Arduino IDE lets you select from one of the installed "boards" (like "Arduino/Genuino Uno" or "Adafruit ESP32 Feather"), and also includes a "Board Manager" choice that allows you to add additional boards that have been prepare by 3rd parties. Many of the boards that used to offer "an Arduino-like IDE" (ChipKit, Launchpad, Maple) have switched over to offering a "board manager" package for the standard IDE instead.

It's an amazing feature - one of the big successes of the Arduino team in the last few years.

Hello westfw

Many thanks for your answer.

I have (almost) an ESP8266.

And you know that I like ( some times) to work in assembler langage.

My English is not so fluent, so it'snt too easy to understand some messages.

Best Regards,
bidouileelec

OK : board == carte as Arduino xxx , es32 , esp8266 , IBM yyy

Thanks all ... and specially to westfw for important notices!

I so ... today for programmers the asm language is a waste of time ...

But can be a wast of time when you go in nature and admire birds singing ? ...

Is same when i wast a little time with asm ...

If you understand nature ... you undestand sense of live!

If you understand asm ... you understand programming!

In my opininon ... any begginer programmer need to begin with asm .

If you know asm ... you know that a variable is in practice is a location of memory , interpreted in many modes by program...

you know that a subroutine is saved address and variables in stack ...

you know registers...

and many things that help you understand how processor and memory works ... and help you

implement the code more efficient...

It is my opinion.

Thanks again!