How to add variables in EdSim51 simulator? - variables

I am using EdSim51 simulator for my project. I have to define a variable called CARD_NO of length 4 bytes and I want to add DS (define storage) of 2bytes to another variable like as shown
CRC_16: DS 2
Can someone help me in defining variables in assembly language
I tried defining a variable like .data section as shown .
org 00h
.data
var1 dw 1000h
var2 dw 2000h
.code
mov ax,bx
add ax,var2
ret
But EDSim51 shows Syntax Error.

Related

How to define and set a variable in ARM DS-5 Debug/Command view on Eclipse CDT

I am using ARM DS-5 (v5.29.1) Eclipse CDT to debug an embedded project, trying to use the debugger command line for manipulating memory locations through the Commands view in the Debug perspective.
According to the debugger's own context help (Ctrl+Space on the command line), the following command should define a variable and set its value:
set variable INTR_MASK=4
However, when typing this, I get an error:
ERROR(EXP8): Could not find the symbol "INTR_MASK"
How can I define and set a variable?
For reference, here's the help description:
set variable
------------
Evaluates an expression and assigns the result to a variable, register or
memory.
Syntax
set [variable] <expression>
Where:
<expression>
Specifies an expression and assigns the result to a variable, register, or
memory address.
Example
set variable myVar=10 # Assign 10 to variable myVar
set variable $PC=0x8000 # Assign address 0x8000 to
# PC register
set variable $CPSR.N=0 # Clear N bit
set variable (*(int*)0x8000)=1 # Assign 1 to address 0x8000
set variable *0x8000=1 # Assign 1 to address 0x8000
set variable strcpy((char*)0x8000,"My String") # Assign string to address 0x8000
set variable memcpy(void*)0x8000,{10,20,30,40},4) # Assign array to address 0x8000
After communicating ARM support, it come out that the right way to achieve that is something like:
newvar $INTR_MASK = (unsigned int)(0x00000004)
set variable $INTR_MASK = (unsigned int)($INTR_MASK + 0x00080000)
... and the associated bonus is that those symbols can be used in the Expressions view as well, so no more explicit addresses, but rather meaningful names.

Declaring 16bit memory variable in assembly

I'm starting to study assembly for PIC18f4550 and I've been trying to do some activities and I don't know how to solve it. According to the activity, Using MPLABX, I'm supposed to sum 2 16bit variables and store the result on a third 16 bit variable.
I was able to sum and store the result on the third variable but I have no idea how to declare these variables in 16bit.
; TODO INSERT CONFIG CODE HERE USING CONFIG BITS GENERATOR
INCLUDE
RES_VECT CODE 0x0000 ; processor reset vector GOTO START ; go to beginning of program
; TODO ADD INTERRUPTS HERE IF USED
MAIN_PROG CODE ; let linker place main program
START
clrw ;clear the w register
num1 equ 00000 ;declares 3 variables and their initial values
num2 equ 00001
result equ 00002
movlw H'4F'
movwf num1
movlw H'8A'
movwf num2
movf num1,W ;moves num1 value to w register
addwf num2,W ;sums num2 and w and stores it in w itself
movwf resultado ;moves w to the result register
END
I need to check if my code is actually correct (Im totally new on assembly) and how to declare these 3 variables in 16bit format. Thanks in advance!
The PIC18 is a 8 bit controller. If you want to add two 16 bit variables you had to do it byte by byte.
Maybe you don't want to work with an absolue address and work with the linker:
udata_acs H'000'
num1_LSB RES 1 ;reserve one byte on the access bank
num1_MSB RES 1 ;
You also could reserve two bytes for a name:
udata_acs H'000'
num1 RES 2 ;reserve two bytes on the access bank
Know you could access the second byte with :
movwf num1+1
And always remember to check the carry bit to get the MSB of an addition.

Assembly x86 - variable assignment

Assume I have a variable called Block_Size and without initialization.
Would
Block_Size db ?
mov DS:Block_Size, 1
be equal to
Block_Size db 1
No, Block_Size db ? has to go in the BSS or data section, not mixed in with your code.
If you wrote
my_function:
Block_Size db ?
mov DS:Block_Size, 1
...
ret
your code would crash. ? isn't really uninitialized, it's actually zeroed. So then the CPU decoded the instructions starting at my_function (e.g. after some other code ran call my_function), it would actually decode the 0 as code. (IIRC, opcode 0 is add, and then the opcode of the mov instruction would be decoded as the operand byte of add (ModR/M).)
Try assembling it, and then use a disassembler to show you how it would decode, along with the hex dump of the machine code.
db assembles a byte into the output file at the current position, just like add eax, 2 assembles 83 c0 02 into the output file.
You can't use db the way you declare variable in C
void foo() {
unsigned char Block_size = 1;
}
A non-optimizing compiler would reserve space on the stack for Block_size. Look at compiler asm output if you're curious. (But it will be more readable if you enable optimization. You can use volatile to force the compiler to actually store to memory so you can see that part of the asm in optimized code.)
Maybe related: Assembly - .data, .code, and registers...?
If you wrote
.data
Block_size db ?
.code
set_blocksize:
mov [Block_size], 1
ret
it would be somewhat like this C:
unsigned char Block_size;
void set_blocksize(void) {
Block_size = 1;
}
If you don't need something to live in memory, don't use db or dd for it. Keep it in registers. Or use Block_size equ 1 to define a constant, so you can do stuff like mov eax, Block_size + 4 instead of mov eax, 5.
Variables are a high-level concept that assembly doesn't really have. In asm, data you're working with can be in a register or in memory somewhere. Reserving static storage for it is usually unnecessary, especially for small programs. Use comments to keep track of what you put in which register.
db literally stands for "define byte" so it will put the byte there, where the move command can have you place a particular value in a register overwriting whatever else was there.

Error: "unknown opcode skipped: 32"

I wrote an 8086 program, and as far as I can tell it runs fine, but when it gets to the part where I declare the variables, the emulator gives me an error. When trying to run the line temp db 0x0F, the emulator says:
unknown opcode skipped: 32
not 8086 instruction - not supported yet.
Here's my full program:
org 100h
mov ah, temp ;put variables into registers
mov al, changed
mov dx, result
lea bx, temp ;get address of temp and put into bx
add dx, [bx] ;add value at the address in bx to result
lea bx, changed ;get address of changed and put into bx
add dx, [bx] ;add value at the address in bx to result
temp db 0x0F ;declare and initialize variables
changed db 32h
result dw 0
Is this consequential to how the program functions, and how do I fix it?
EDIT: sigjuice solved the problem, as you can see in the comments. Here's the final version of the program that runs correctly:
.CODE
org 100h
mov ah, temp ;put variables into registers
mov al, changed
mov dx, result
lea bx, temp ;get address of temp and put into bx
add dx, [bx] ;add value at the address in bx to result
lea bx, changed ;get address of changed and put into bx
add dx, [bx] ;add value at the address in bx to result
.DATA
temp db 0x0F ;declare and initialize variables
changed db 32h
result dw 0
add dx, [bx] ;add value at the address in bx to result
temp db 0x0F ;declare and initialize variables
In this part of your program there's nothing that stops the CPU from executing the data at the temp label as if it were an instruction.
Although adding the .CODE and .DATA assembler directives (perhaps suggested by #sigjuice) seemingly solves the problem, this is typically not what you use when writing a .COM executable. It's a .COM executable because you used the org 100h directive.
What your program really needs is a way to return to the operating system. Since this is EMU8086 the preferred way is using the DOS.TerminateWithReturncode function.
add dx, [bx] ;add value at the address in bx to result
; Exit to the operating system
mov ax, 4C00h ;AH=4Ch function number, AL=0 exitcode (0 most often means OK)
int 21h ;DOS system call
; Now beyond this point nothing gets executed inadvertently
temp db 0Fh ;declare and initialize variables
I can't really advice to return to the operating system using a mere ret instruction, because this method requires that the SS:SP registers are set as they were when the program started. This will not always be the case. Better use this DOS function that does not rely on any specific register setting.
lea bx, temp ;get address of temp and put into bx
add dx, [bx] ;add value at the address in bx to result
lea bx, changed ;get address of changed and put into bx
add dx, [bx] ;add value at the address in bx to result
Nothing to do with your original problem but as a bonus:
Because temp and changed are both byte-sized variables, the word-sized additions don't just add the variables alone but also the byte that happens to follow them in memory! Sometimes this is intentional (I sincerily doubt this is the case here!), but you need to make sure that you understand this.

Find and Replace an operation in Verilog using Yosys

I am trying to see if Yosys fits my requirements or no.
What i want to do is to find an operation in Verilog code (e.g. temp = 16*val1 + 8*val2 ) and replace this with another op like ( temp = val1 << 4 + val2 << 3 ).
Which parts i need to learn & use from Yosys? if anyone knows the set of command to use, can he/she please let me know to boost my learning curve ?
Thanks.
For example consider the following verilog input (test.v):
module test(input [7:0] val1, val2, output [7:0] temp);
assign temp = 16*val1 + 8*val2;
endmodule
The command yosys -p 'prep; opt -full; show' test.v will produce the following circuit diagram:
And the output written to the console contains this:
3.1. Executing OPT_EXPR pass (perform const folding).
Replacing multiply-by-16 cell `$mul$test.v:2$1' in module `\test' with shift-by-4.
Replacing multiply-by-8 cell `$mul$test.v:2$2' in module `\test' with shift-by-3.
Replacing $shl cell `$mul$test.v:2$1' (B=3'100, SHR=-4) in module `test' with fixed wiring: { \val1 [3:0] 4'0000 }
Replacing $shl cell `$mul$test.v:2$2' (B=2'11, SHR=-3) in module `test' with fixed wiring: { \val2 [4:0] 3'000 }
The two lines reading Replacing multiply-by-* cell are the transformation you mentioned. The two lines after that replace the constant shift operations with wiring, using {val1[3:0], 4'b0000} and {val2[4:0], 3'b000} as inputs for the adder.
This is done in the opt_expr pass. See passes/opt/opt_expr.cc for its source code to see how it's done.