Getting Error saying Bad register symbol name"" - arm

; Call a function "high" to find the largest element in array A
AREA |.text|, CODE, READONLY
EXPORT high
high
MOV R1,#0 ; Set R1 to 0
MOV R2,#0 ; Set R2 to 0
LDR R3,[A,R1] ; Load the first element in array A
LDR R4,[A]; Load the first element in array A
MOV R5,#5 ; Set R5 to the size of array A
Here While building the program I am getting an error saying "Bad register symbol, expected Integer register".

Related

Writing in the Data Area of ARM

I am writing a bubble sort in ARM Assembly on the STM32.
AREA Data1,DATA,READWRITE
ARR DCD 1,3,2,4
How can I write a value to the array in the data area? I am using LDR,=ARR to load the address of ARR. However, when I check the memory, the values are all zero.
AREA main, CODE, READONLY
EXPORT __main
__main
MOV R4,#4; LENGTH OF ARRAY
MOV R5,#3; NUMBER OF ITERATIONS
MOV R6,#3; NUMBER OF COMPARISONS
LDR R0,=ARR; ADDRESS OF ARR[0] FROM DATA AREA
__LOOP1
CMP R5,#0
BEQ __done
CMP R6,#0
BEQ __L2;
LDR R2,[R0,#4]; R2=ARR[i+1]
LDR R1,[R0];
MOV R3,R1;
CMP R1,R2;
BLE __L1;
STR R2,[R1];
STR R3,[R0];
__L1
SUBS R6,#1;
ADDS R0,#4;
B __LOOP1;
__L2
SUBS R5,#1;
MOV R6,R5;
LDR R0,=ARR;
B __LOOP1;
__done
AREA A,DATA,READWRITE
ARR DCD 1,3,2,4
END

ARM assembly - invalid immediate operand value

The question is "Store the data to the memory location 1001h, ..(1001h+10) and copy the data in reverse order in memory location 2001...(2001+h)" I keep getting the run time error invalid immediate operand value
immediate must be creatable by rotating an 8-bit number right within a 32bit word.
How do i fix it?
MVN R2,#0x1001
MOV R3,#0x2000
MOV R4,#0X01
MOV R0,#0X10
LOOP
STRB R4,[R2]
LDRB R5,[R2]
STRB R0,[R3]
ADD R2,R2,#0x01
ADD R3,R3,#0x01
ADD R4,R4, #0x01
SUB R0,R0, #0x01
CMP R0,#0x01
BNE LOOP
END

find number in array using stack in Assembly 8086

i have an assignment to write program in Assembly lang that accepts 3 parameters to the stack and search n value in the array.
here is the full Explain the assignment:
Write a procedure must be written that accepts three parameters on the
stack: a word array address, the number of objects in the array, and a
number (we will denote it here in n). The procedure will look for n in
the array and return in the ax register the address of the first
element in the array whose value is equal to n. Ax register. If value
is not in array, return -1. In the data segment, two word sets of
different lengths must be defined with different values. You must
write a main procedure that runs the find procedure for each of the
two configured arrays, with two different search values. The search
values ​​will appear in another setting in the data segment. The main
procedure prints the address where the value is located, or a note if
it is not found. Reminder: Sets a word layout of 4: arr1 dw 300, 50,
15, 48
i need help with how to start the code? how to send the parameters to the stack?
Thanks in advance for helpers
edit this is my code for now:
.STACK 64
.DATA
arr db 9 dup ?
arr1 dw 1,2,3,4,5
arr1size dw 5
newline db 0AH,0DH,'$' ; newline
arr2 dw 4,5,6,7,10,10
arr2size dw 6
resu dw ? ; result var
errmsg db "of - voer flow"
n dw 0
sendToStack proc
push bp
mov bp, sp
sub sp, 24
lea dx, arr1
push dx
pop dx
pop bp
end proc
start:
mov ax, #data
mov ds, ax
call sendToStack
end
suggestions for continue?
Here is a code I developed on Linux for 32-bit x86 architecture which finds a number inside an array. The code might help you get started, but is NOT using stack, therefore the stack version remains a homework for you. I tested the code with gdb debugger to step through the instructions and check the register values, as far as I checked, the code works as expected.
We have the following makefile, so on linux terminal just type make and the assembly code inside asmtut.s file is compiled and linked:
asmtut: asmtut.o
ld -o asmtut asmtut.o
asmtut.o: asmtut.s
nasm -f elf -o asmtut.o asmtut.s
clean:
rm *.o asmtut
The assembly code inside asmtut.s is:
section .data
array dw 18,99,22,72,40,55,110,23 ; array to be searched
length dd 8 ; array length; note array length can be 32-bit
number dw 40 ; number we search for, i.e. wanted number
;number dw 88 ; this number will NOT be found: to check the not_found fork of the program
index dd 0 ; index of found number ; will be -1 if not found; note index is 32-bit
section .text
global _start
_start:
xor edi, edi ; set edi=0x00 ; stores current array element index; use 0-based indexing
xor ax, ax ; set ax=0x00 ; stores current array element
xor ebx, ebx ; ebx is used as an intermediary to store 32-bit index
jmp loop ; start the search loop
loop:
mov ax, [array+edi*2] ; move first array element to ax; note a word is 16bits=2bytes
cmp ax, [number] ; compare array element with wanted number
je found ; if equal, wanted value is found: jump to "found" address
inc edi ; increment element index
cmp edi, [length] ; see if the element was the last element:
je not_found ; if so, the wanted number if not found, jump to "not_found"
jmp loop ; repeat the loop
found:
mov ebx, edi ; wanted number is found: use "ebx" as an intermediary to store index
mov [index], bx ; store index to memory location for index
jmp end
not_found:
mov ebx, -1 ; wanted number is NOT found: use "ebx" as an intermediary to store -1
mov [index], ebx ; move -1 to the memory location for index
jmp end
end:
mov bx, 0 ; move interrupt argument to bx
mov ax, 1 ; move "1" to ax which means "exit" interrupt
int 0x80 ; interrupt: exit

ARM Assembly, Keil Microvision 4; Working with non-zero registry values

Hoping for just a bit of help with something.
I have a college assignment which involves making what is basically a calculator that takes values entered in by the user as a string of ASCII characters and stores and displays the entered value, as well as making various computations such as sum, min, etc. and stores them all as well. The code only executes after a value is entered.
My code itself is working how I need it to so far, and I think I know how to write in all the computations, but my issue is that most of the registers hold non-zero values from the start, and so if I start adding in values to a register right away -- for the sum, for instance -- the end value will be incorrect. I can't just use LDR and set them to zero beforehand, though, since that will happen every time the code is run, and I need to keep the added values around to make the computations each time.
I don't know if I'm overthinking this or if there's something really simple that I'm missing, but I can't think of a way to do what I need to with non-zero registry values.
This is my working code so far:
AREA ConsoleInput, CODE, READONLY
IMPORT main
IMPORT getkey
IMPORT sendchar
EXPORT start
PRESERVE8
start
read
LDR R7, =0
BL getkey ; read key from console
CMP R0, #0x0D ; while (key != CR)
BEQ endRead ; {
BL sendchar ; echo key back to console
;R4 is used to store the hex value of whatever is entered (as a full number)
;R5 stored the entered input safely (as R0 can change)
;R6 holds the constant 10, for increasing successive entries by a base of ten
;R10 is where successive values are multiplied by 10
;R11 is used to hold the count (+1 each time the code is run)
LDR R6, =10
MUL R10, R6, R10
MOV R5, R0
AND R5, R5, #&F
ADD R10, R10, R5
MOV R4, R10 ;NUMBER ENTERED SENT TO R4
ADD R11, R11, #1 ;COUNT
B read ; }
endRead
stop B stop
END

ARM Assembly error: A1898E: Target cannot be relocated. No suitable relocation exists for this instruction

I am trying to write simple program to sum up data in array, but I get this error
error: A1898E: Target cannot be relocated. No suitable relocation exists for this instruction
Here is my code
AREA SUMARRAY, CODE, READONLY
EXPORT __main
ENTRY
__main
LDR r2, LENGTH
SUB r2, r2, #1 ; r2 contains (LENGTH-1)
MOV r6, #0 ; r6 sum set to 0
FOR_INIT MOV r1, #0 ; r1 index I set to 0
ADR r3, ARRAY ; start r3 with address of A[0]
FOR_CMP CMP r1, r2 ; compare I and (LENGTH-1)
BGT END_FOR ; drop out of loop if I < (LENGTH-1)
LDR r4, [r3],#4 ; load r4 with A[I] then walk r3 down ARRAY
ADD r6, r6, r4 ; update sum with A[I]
ADD r1, r1, #1 ; increment I
B FOR_CMP ; loop back to for-loop check
END_FOR
STR r6, SUM ; store result in SUM
STOP B STOP
AREA my_data, DATA, READWRITE
ALIGN
SUM DCD 0XFFFFFFFF
ARRAY DCD 1,5,20,32,13,66,3,5,23,64,112,66,22
LENGTH DCD 13
Compiler says that problem is in this line
ADR r3, ARRAY ; start r3 with address of A[0]
What is wrong with this code ? Could someone explain why this error appears ?
And how can I fix it ?
Thanks.
UPDATE
AREA Sorting, CODE, READONLY
EXPORT __main
ENTRY
__main
LDR r2, LENGTH
SUB r2, r2, #1 ; r2 contains (LENGTH-1)
MOV r6, #0 ; r6 sum set to 0
FOR_INIT MOV r1, #0 ; r1 index I set to 0
LDR r3, =ARRAY ; start r3 with address of A[0]
FOR_CMP CMP r1, r2 ; compare I and (LENGTH-1)
BGT END_FOR ; drop out of loop if I < (LENGTH-1)
LDR r4, [r3],#4 ; load r4 with A[I] then walk r3 down ARRAY
ADD r6, r6, r4 ; update sum with A[I]
ADD r1, r1, #1 ; increment I
B FOR_CMP ; loop back to for-loop check
END_FOR
STR r6, SUM ; store result in SUM
STOP B STOP
LTORG
AREA my_data, DATA, READWRITE
ALIGN
SUM DCD 0XFFFFFFFF
ARRAY DCD 1,5,20,32,13,66,3,5,23,64,112,66,22
LENGTH DCD 13
But in this case I get errors
Error: L6286E: Relocation #REL:0 in sorting.o(SUMARRAY) with respect to LENGTH. Value(0x3fffff18) out of range(0 - 0xfff) for (R_ARM_LDR_PC_G0)
Error: L6286E: Relocation #REL:1 in sorting.o(SUMARRAY) with respect to SUM. Value(0x3ffffeb4) out of range(0 - 0xfff) for (R_ARM_LDR_PC_G0)
From the documentation for ADR:
If expression is program-relative, it must evaluate to an address in the same code area as the ADR pseudo-instruction. Otherwise the address may be out of range after linking.
So one way of fixing the problem could be to move ARRAY to the same code AREA as the ADR instruction that references ARRAY.
Another possible solution would be to use the pseudo-version of LDR to load the address. That is, instead of ADR r3,ARRAY, use LDR r3,=ARRAY (note the = sign).
This way you should be able to keep ARRAY in the data AREA. Note that you may have to place an LTORG directive after the end of your main function.

Resources