Answers.Body: <p>It looks like the disassembler you used doesn't show the complete picture. Like many programming languages, the <code>lmsasm</code> language allows allocating variables with either a global scope or a local scope.</p>
  <p>I wrote a <a href="https://github.com/dlech/lms-hacker-tools/blob/master/EV3/lmsdisasm.py" rel="nofollow noreferrer">disassembler in Python</a> that will create a <code>.lms</code> file that can be recompiled with the <a href="https://github.com/ev3dev/lmsasm" rel="nofollow noreferrer">lmsasm assembler</a>. Using this disassembler should show the actual allocations, although not with the correct data types.</p>
  <p>To explain it better, consider this example:</p>
  <pre><code>DATA32 MyGlobalInt
  
  subcall MySubroutine1
  {
    DATA32 MyLocalInt
  
    // subcall can use both global and its own local variables
    ADD32(MyGlobalInt, 10, MyLocalInt) // MyLocalInt = MyGlobalInt + 10
    ...
  }
  
  subcall MySubroutine2
  {
    ADD32(MyGlobalInt, 10, MyLocalInt) // ERROR! MyLocalInt is not defined
  
    // we could define MyLocalInt at the start of this subcall
    // to fix the error, but it would be a new variable, not
    // related to the one with the same name in MySubroutine1
    ...
  }
  
  ...
  </code></pre>
  <p>Global variables are declared at the top level of the file and can be used in any blocks (<code>subcall</code>, <code>vmthread</code>, etc.) and will have the same value everywhere.</p>
  <p>Local variables are declared inside of a block (between curly braces). Those variables can only be accessed in that block and the value does not persist between calls of that block.</p>
  <hr />
  <p>Direct commands also run as a program. They just have more limited rules compared to a user program.</p>
  <p>So, to answer the fundamental question: memory isn't directly shared between programs.</p>
  <p>However, there are some opcodes that can be used to access memory in other programs.</p>
  <p>From <a href="http://ev3.fantastic.computer/doxygen/VM.html" rel="nofollow noreferrer">http://ev3.fantastic.computer/doxygen/VM.html</a>:</p>
  <blockquote>
  <p><strong>opMEMORY_WRITE (PRGID, OBJID, OFFSET, SIZE, ARRAY)</strong></p>
  <p>Write VM memory</p>
  <p>Dispatch status unchanged</p>
  <p>Parameters</p>
  <ul>
  <li>(DATA16)    PRGID - Program slot number (must be running) (see <a href="http://ev3.fantastic.computer/doxygen/programid.html#prgid" rel="nofollow noreferrer">prgid</a>)</li>
  <li>(DATA16)    OBJID - Object id (zero means globals)</li>
  <li>(DATA32)    OFFSET - Offset (start from)</li>
  <li>(DATA32)    SIZE - Size (length of array to write)</li>
  <li>(DATA8) ARRAY - First element of DATA8 array to write</li>
  </ul>
  <p><a href="http://ev3.fantastic.computer/doxygen/directcommands.html#opMEMORY_WRITE1" rel="nofollow noreferrer">Direct command example</a></p>
  <p><strong>opMEMORY_READ (PRGID, OBJID, OFFSET, SIZE, ARRAY)</strong></p>
  <p>Read VM memory</p>
  <p>Dispatch status unchanged</p>
  <p>Parameters</p>
  <ul>
  <li>(DATA16)    PRGID - Program slot number (must be running) (see <a href="http://ev3.fantastic.computer/doxygen/programid.html#prgid" rel="nofollow noreferrer">prgid</a>)</li>
  <li>(DATA16)    OBJID - Object id (zero means globals)</li>
  <li>(DATA32)    OFFSET - Offset (start from)</li>
  <li>(DATA32)    SIZE - Size (length of array to read)</li>
  </ul>
  <p>Returns</p>
  <ul>
  <li>(DATA8) ARRAY - First element of DATA8 array to receive data</li>
  </ul>
  <p><a href="http://ev3.fantastic.computer/doxygen/directcommands.html#opMEMORY_READ1" rel="nofollow noreferrer">Direct command example</a></p>
  </blockquote>
  <hr />
  <p>Using these instructions seems dangerous since one program doesn't really know what is running in the other slot, so you may or may not be reading from the memory you intended to and writing to the wrong memory could cause crashes or other unexpected behavior.</p>
  <p>Instead, I would recommend using the mailbox opcodes to transfer information between programs if needed.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-15T17:46:45.970Z
Answers.Text: Thank You for the explanation, but I still want to know is a user program shares memory parts with direct commands like imagine: a user wrote a program, deployed it to a ev3 brick and in the program there is a block like measuring touch sensor (the value of which is not wired to anywhere), so would the value placed anywhere in memory and if yes - could it be accessed by direct commands?
Answers.UserDisplayName: crackanddie
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-15T23:19:39.340Z
Answers.Text: No, memory is not shared directly between a user program and direct commands. However, there are some instructions you can use to access memory in other programs. I will add these to my answer.
Answers.UserDisplayName: David Lechner
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-15T15:32:15.003Z
Answers.LastActivityDate: 2023-11-15T23:33:28.420Z
Answers.LastEditDate: 2023-11-15T23:33:28.420Z
Answers.UserDisplayName: David Lechner
Body: <p>I've learned a bit about Direct Commands in EV3 and understood the work of Local and Global memory. Using the Direct Commands I can access the memory using an offset of the accessing byte/bytes (like if I want to access the byte 4 - I could write smth like <code>LVX(4)</code> (if I use already prepared library)). Now I want to work with <em>.rbf</em> files and found a cool <a href="https://gitlab.com/attila.farago.hu/ev3brickmagic" rel="nofollow noreferrer">repo</a> that can decompile it into something readable.<br />
  <a href="https://i.sstatic.net/ZfrVw.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ZfrVw.png" alt="enter image description here" /></a><br />
  And then to this:<br />
  <a href="https://i.sstatic.net/C5IjE.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/C5IjE.png" alt="enter image description here" /></a><br />
  Now  I really don't understand what is going on. I had some other programs decompiled and as I understood these thing like <code>$LOCAL4</code> the number in it is directing not to a offset of bytes but bits. There were also some locals like <code>$LOCAL120</code> and <code>$LOCAL121</code>.<br />
  I want to understand is there something common between these local things? And is there docs about memory used by <em>.rbf</em> files?</p>
  
Tags: <ev3><programming>
Title: What is the difference between LOCAL memory for programs and LOCAL memory for Direct Commands?
UserDisplayName: crackanddie
ThreadText: # What is the difference between LOCAL memory for programs and LOCAL memory for Direct Commands?
  
  (Asked by: username_0 on 2023-11-14)
  
  I've learned a bit about Direct Commands in EV3 and understood the work of Local and Global memory. Using the Direct Commands I can access the memory using an offset of the accessing byte/bytes (like if I want to access the byte 4 - I could write smth like `LVX(4)` (if I use already prepared library)). Now I want to work with *.rbf* files and found a cool [repo](https://gitlab.com/attila.farago.hu/ev3brickmagic) that can decompile it into something readable.  
  [![enter image description here](https://i.sstatic.net/ZfrVw.png)](https://i.sstatic.net/ZfrVw.png)  
  And then to this:  
  [![enter image description here](https://i.sstatic.net/C5IjE.png)](https://i.sstatic.net/C5IjE.png)  
  Now I really don't understand what is going on. I had some other programs decompiled and as I understood these thing like `$LOCAL4` the number in it is directing not to a offset of bytes but bits. There were also some locals like `$LOCAL120` and `$LOCAL121`.  
  I want to understand is there something common between these local things? And is there docs about memory used by *.rbf* files?
  
  **Tags:** ev3, programming
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-11-15. Score: 2 | Accepted answer
  
  It looks like the disassembler you used doesn't show the complete picture. Like many programming languages, the `lmsasm` language allows allocating variables with either a global scope or a local scope.
  
  I wrote a [disassembler in Python](https://github.com/dlech/lms-hacker-tools/blob/master/EV3/lmsdisasm.py) that will create a `.lms` file that can be recompiled with the [lmsasm assembler](https://github.com/ev3dev/lmsasm). Using this disassembler should show the actual allocations, although not with the correct data types.
  
  To explain it better, consider this example:
  
  ```
  DATA32 MyGlobalInt
  
  subcall MySubroutine1
  {
    DATA32 MyLocalInt
  
    // subcall can use both global and its own local variables
    ADD32(MyGlobalInt, 10, MyLocalInt) // MyLocalInt = MyGlobalInt + 10
    ...
  }
  
  subcall MySubroutine2
  {
    ADD32(MyGlobalInt, 10, MyLocalInt) // ERROR! MyLocalInt is not defined
  
    // we could define MyLocalInt at the start of this subcall
    // to fix the error, but it would be a new variable, not
    // related to the one with the same name in MySubroutine1
    ...
  }
  
  ...
  
  ```
  
  Global variables are declared at the top level of the file and can be used in any blocks (`subcall`, `vmthread`, etc.) and will have the same value everywhere.
  
  Local variables are declared inside of a block (between curly braces). Those variables can only be accessed in that block and the value does not persist between calls of that block.
  
  ---
  
  Direct commands also run as a program. They just have more limited rules compared to a user program.
  
  So, to answer the fundamental question: memory isn't directly shared between programs.
  
  However, there are some opcodes that can be used to access memory in other programs.
  
  From <http://ev3.fantastic.computer/doxygen/VM.html>:
  
  > **opMEMORY\_WRITE (PRGID, OBJID, OFFSET, SIZE, ARRAY)**
  >
  > Write VM memory
  >
  > Dispatch status unchanged
  >
  > Parameters
  >
  > * (DATA16) PRGID - Program slot number (must be running) (see [prgid](http://ev3.fantastic.computer/doxygen/programid.html#prgid))
  > * (DATA16) OBJID - Object id (zero means globals)
  > * (DATA32) OFFSET - Offset (start from)
  > * (DATA32) SIZE - Size (length of array to write)
  > * (DATA8) ARRAY - First element of DATA8 array to write
  >
  > [Direct command example](http://ev3.fantastic.computer/doxygen/directcommands.html#opMEMORY_WRITE1)
  >
  > **opMEMORY\_READ (PRGID, OBJID, OFFSET, SIZE, ARRAY)**
  >
  > Read VM memory
  >
  > Dispatch status unchanged
  >
  > Parameters
  >
  > * (DATA16) PRGID - Program slot number (must be running) (see [prgid](http://ev3.fantastic.computer/doxygen/programid.html#prgid))
  > * (DATA16) OBJID - Object id (zero means globals)
  > * (DATA32) OFFSET - Offset (start from)
  > * (DATA32) SIZE - Size (length of array to read)
  >
  > Returns
  >
  > * (DATA8) ARRAY - First element of DATA8 array to receive data
  >
  > [Direct command example](http://ev3.fantastic.computer/doxygen/directcommands.html#opMEMORY_READ1)
  
  ---
  
  Using these instructions seems dangerous since one program doesn't really know what is running in the other slot, so you may or may not be reading from the memory you intended to and writing to the wrong memory could cause crashes or other unexpected behavior.
  
  Instead, I would recommend using the mailbox opcodes to transfer information between programs if needed.
  
  > **Comments:**
  > **username_0**: Thank You for the explanation, but I still want to know is a user program shares memory parts with direct commands like imagine: a user wrote a program, deployed it to a ev3 brick and in the program there is a block like measuring touch sensor (the value of which is not wired to anywhere), so would the value placed anywhere in memory and if yes - could it be accessed by direct commands?  
  > **username_1**: No, memory is not shared directly between a user program and direct commands. However, there are some instructions you can use to access memory in other programs. I will add these to my answer.  
  
  ---
  
  