Define and access an array in x86 assembly TASM - arrays

I am trying for hours and hours to access an array in assembly x86 TASM using dosbox - but I always get 'Operand types do not match' or 'Pointer expression needs brackets' error - I've searched the whole internet and couldn't find something that works in TASM x86.. this is the code:
IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
A DB 1, 2, 3, 4, 5, 6, 7, 8, 10, 11
; --------------------------
CODESEG
start:
mov ax, #data
mov ds, ax
; --------------------------
mov al,A[0]
; --------------------------
exit:
mov ax, 4c00h
int 21h
END start
Changing the line to:
mov ax, BYTE PTR A[0]
or to:
mov ax, A[BYTE PTR 0]
And even changing ax or al with all these combinations is failing.. or trying to acces the OFFSET of array A:
mov al, A[OFFSET A]
I don't know where's the problem..
Thank you for helping!

Related

im having a PANIC when running some assembly in bochs

this image showcase the error im getting when running the command "bochs" in the bootDIr directory where my assembly file , the image ,the binary and the script are at , the tutorial i watched was using ubuntu while im using kali,i dont think that was relevant but i would love your help
the goal is to show the "Hello" String when booting (+some messages generated by the emulator)
here is the nasm code:
[BITS 16]
[ORG 0x7c00]
start :
xor ax,ax
mov ds,ax
mov es,ax
mov ss, ax
mov sp, 0x7c00
PrintMessage :
mov ah,0x13
mov al, 1
mov bx,0xa
xor dx,dx
mov bp, Message
mov cx, MessageLen
int 0x10
End :
hlt
jmp End
Message : db "Hello"
MessageLen : equ $-Message
times (0x1be -($-$$)) db 0
db 80h
db 0,2,0
db 0f0h
db 0ffh,0ffh,0ffh
dd 1
dd (20*16*63 - 1 )
times (16*3) db 0
db 0x55
db 0xaa

Assembly Language x86 - Registers Set and Arithmetic and Loop

I am trying to solve this problem about loops. I am using a push and pop method instead of using a separate register to store data.
.model small
.stack
.code
m proc
mov ax,0b800h
mov es,ax
mov di,7d0h
mov ah,7 ; normal attribute
mov al,'A'
mov cx,5
x: stosw
push ax ;mov dl,al ; dl='A'
push di
mov al,'1'
stosw
pop di
add di,158
pop ax ;mov al,dl
inc al
loop x
mov ah,4ch
int 21h
m endp
end m
I am unable to loop the mov al, '1'.
The output should be like this:
A1
B2
C3
D4
E5
Can anyone show the correct code? Thank you.
Consider the ASCII codes involved:
Letter Digit Difference
A1 65 49 16
B2 66 50 16
C3 67 51 16
D4 68 52 16
E5 69 53 16
See how the difference is always 16 ? That's what next solution exploits:
...
mov ax, 0700h + 'A' ; WhiteOnBlack 'A'
x: stosw ; Stores one letter from {A, B, C, D, E}
sub al, 'A' - '1' ; Convert from letter to digit
stosw ; Stores one digit from {1, 2, 3, 4, 5}
add al, 'A' - '1' + 1 ; Restore AL and at the same time increment
add di, 160 - 4 ; Move down on the screen
cmp al, 'E'
jbe x
...
You don't always need to use CX and the LOOP instruction to work with a loop. Anyway the LOOP instruction is to be avoided for speed reasons!

Assembly x86 putting values into array with loop

I wanted to put numbers in an array of length 10, but each number is 1 bigger than the last number.
It means: myArray = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
I have tried this:
IDEAL
MODEL small
STACK 100h
DATASEG
intArray db 10 dup (0)
index db 1
CODESEG
start:
mov ax, #DATA
mov ds, ax
loopArray:
mov al, [index]
add [intArray+index], al ; here is the problem
inc [index]
cmp [index], 11
jb loopArray
exit:
mov ax, 4c00h
int 21h
END start
But I can't add the index to [intArray + index], so I tried to to add it to [intArray+al], and that doesn't work either.
How can I add the index to the next array's value each time?
myArray = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
These are the numbers that you want your array to contain. But since you initialized the index variable (that you will be using for both indexing and storing) as 1 (using index db 1) this will lead to another result.
Just setup the index with:
index db 0
There's another reason to set it up this way!
In the notation [intArray+index] the index part is meant to be an offset in the array. Offsets are always zero based quantities. The way you wrote your program, it will write the 10th value behind the array.
add [intArray+index], al ; here is the problem
You're right that this is the problem. Some assemblers won't compile this, and others will just add the addresses of both these variables. Neither suits your purpose. What you need is putting the content of the index variable in a register and use that combination of operands.
intArray db 10 dup (0)
index db 0
...
loopArray:
movzx bx, [index]
mov [intArray+bx], bl ;Give the BX-th array element the value BL
inc [index]
cmp [index], 10
jb loopArray
With this code the index will start at 0 and then the loop will continu for as long as the index is smaller than 10.
Of course you could write this program without using an index variable at all.
intArray db 10 dup (0)
...
xor bx, bx ;This make the 'index' = 0
loopArray:
mov [intArray+bx], bl ;Give the BX-th array element the value BL
inc bx
cmp bx, 10
jb loopArray
Given that the array was initially filled with zeroes, you can replace the:
mov [intArray+bx], bl ;Give the BX-th array element the value BL
with:
add [intArray+bx], bl ;Give the BX-th array element the value BL
Do remember this can only work if the array was filled with zeroes beforehand!

x86 real mode: move data from one array to another

Here is my code:
data segment
gio db 1,2,3,4,5,6
ricxvi db 1
jami db 0
x db ?
ends
stack segment
db 128 dup(0)
ends
code segment
start:
MOV AX,DATA
MOV DS,AX
mov cx, 6
lea si, gio
mov ah, 0
n1:
mov al, [si]
cmp ricxvi, 3
je n2
jmp n3
n2:
add jami, al
mov ricxvi, 1
jmp n4
n3:
add ricxvi, 1
push ax
n4:
add si, 1
add di, 1
loop n1
mov ricxvi, 1
mov ax, 0
mov cx, 6
lea si, gio
n5:
cmp ricxvi, 3
je n6
jmp n7
n6:
mov ricxvi, 1
add si, 1
loop n5
n7:
pop [si]
add si, 1
loop n5
mov ax, 4c00h
int 21h
ends
end start
I have a array named gio And I'm trying to reverse this array but leave every 3th element on its position. Meaning I want to get the output like this 5,4,3,2,1,6 but As I inspect variables, in array I have 5,4,2,1,B8. I have noticed that when program first hits pop [si] whole array changes, exploring variables shows me that its 5, NULL, 3, 4, 5, 6 should it not be 5,2,3,4,5,6? I'm using emu8086. Question may sound silly as I'm new with assembly. Thanks.
There are three errors :
You are poping two bytes into [si] but you only need one byte. The solution is to pop two bytes into a register and move one byte into [si].
Under label n6 you got loop n5, but when cx becomes zero the loop doesn't jump and the block n7 is executed when it shouldn't.
You forgot to increase the "3" counter under label n7.
Here are the fixes :
n6:
mov ricxvi, 1
add si, 1
loop n5
jmp finale ;◄■■ SKIP NEXT BLOCK WHEN CX=0.
n7:
add ricxvi, 1 ;◄■■ INCREASE THE "3" COUNTER.
pop ax ;◄■■ POP TWO BYTES.
mov [si], al ;◄■■ USE ONE BYTE ONLY.
add si, 1
loop n5
finale: ;◄■■ END LABEL.
mov ax, 4c00h
int 21h

Assembly Language (Order Taker)

I'm trying hard to study Assembly language.
I really need help to store different 10 items in an array
I want to build a program that will accept items from 10 choices and it will store it.
Those 10 items have different value.
Example
Item 1 = 10$
Item 2 = 4$
So that when the User tries to choose Item1 and Item2 it will show the
sum of both items.
I'll be gladly be happy if someone can share his/her own code that can store 10 items with the sum of all items. Thanks
Here's my code:
_start:
mov eax,3 ;number bytes to be summed
mov ebx,0 ;EBX will store the sum
mov ecx, x ;ECX will point to the current element to be summed
top: add ebx, [ecx]
add ecx,1 ;move pointer to next element
dec eax ;decrement counter
jnz top ;if counter not 0, then loop again
done:
add ebx, '0'
mov [sum], ebx ;done, store result in "sum"
display:
mov edx,1 ;message length
mov ecx, sum ;message to write
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
global x
x:
db 2
db 4
db 3
sum:
db 0
My code here does have problem.
x:
db 2
db 4
db 3
sum:
db 0
Since you've defined all of your variables to be of byte type, you must process them as bytes! You're reading and writing dwords in your program.
This could have been OK:
top: add bl, [ecx]
add ecx, 1 ;move pointer to next element
dec eax ;decrement counter
jnz top ;if counter not 0, then loop again
done:
add bl, '0'
mov [sum], bl ;done, store result in "sum"

Resources