Reputation: 63
I have declared an array of 8 elements each of size two bytes.
ar dw 8 dup(6)
How can I change the value of the last index of this array(ar)?
Upvotes: 1
Views: 295
Reputation: 87
@fuz's comment was enough to answer your question.
mov word [ar+2*7], 7
===
The index of your first element is [ar].
Your array has 8 elements each of size two bytes (a word).
So naturally the last index would be [ar+2*(8-1)]. ([ar+16] wouldn't be within the bounds of the array as it would refer to the next two bytes).
===
Just in case if you're thinking why other possibilities are being neglected, here's a short explanation for you.
The instruction mov
is used to transfer a value between two registers or a register and a memory location. Memory to Memory transfer isn't possible due to it's physical limitations. You can use a temporarily use a register to achieve it though. (3 ins)
Note: Transfer means copy.
Now by default mov transfers a byte to a memory location, if it's a raw value or the it's the higher or lower byte of a register.
To keep things short we can use word to tell the assembler that the given address will receive a 2 byte value, so manage the transfer accordingly.
===
Upvotes: 0
Reputation: 14409
Here's a template of a TASM program for you:
.MODEL small
.486
.STACK 1000h
.DATA
ar DW 8 DUP (6)
decstr DB 8 ('$')
.CODE
main PROC
mov ax, @DATA ; Initialize DS - Don't forget it!
mov ds, ax
; You might count the array from 1 to 8, but the computer counts from 0 to 7.
; So, decrement the wished index by 1: (LENGTH arr - 1)
; Since a WORD consumes 2 bytes, the index has to be multiplied by this size,
; so that the computer can point into the array at the right address.
; The size of a WORD (2 bytes) can be determined by the directive TYPE
LASTINDEX = (LENGTH ar - 1) * TYPE ar
mov [ar + LASTINDEX], 7
; Print the decimal numbers of the array to the console
lea si, [ar] ; SI gets the address of ar
mov cx, 8 ; Counter - do the loop eight times
L1:
mov ax, [si] ; AX gets the value of the element
lea di, [decstr] ; DI gets the address of decstr
call ax2dec
mov WORD PTR [di], '$ ' ; Insert a space into the string
mov ah, 09h ; DOS function: print string
lea dx, [decstr] ; DX gets the address of decstr
int 21h ; Call DOS
add si, 2 ; Set the pointer to the next element
loop L1 ; Do it CX times
mov ax, 4C00h ; DOS function:Exit with Code 0
int 21h ; Call DOS
main ENDP
ax2dec PROC STDCALL USES ax bx cx dx es ; Args: AX - number; DI - pointer to string
push ds ; Initialize ES for STOSB
pop es
mov bx, 10 ; Base 10 -> divisor
xor cx, cx ; CX=0 (number of digits)
Loop_1:
xor dx, dx ; Clear DX for division
div bx ; AX = DX:AX / BX Remainder DX
push dx ; Push remainder for LIFO in Loop_2
inc cx ; inc cl = 2 bytes, inc cx = 1 byte
test ax, ax ; AX = 0?
jnz Loop_1 ; No: once more
Loop_2:
pop ax ; Get back pushed digits
or al, 00110000b ; Conversion to ASCII
stosb ; Store only AL to [ES:DI] (DI is a pointer to a string)
loop Loop_2 ; Until there are no digits left
mov byte ptr es:[di], '$' ; Termination character for 'int 21h fn 09h'
ret
ax2dec ENDP ; Ret: DI - pointer to terminating '$'
END main ; Directive to stop the compiler.
If the examples of your teacher differ, then ask them why! TASM is ancient, but its teachers are even more ancient ;-)
Upvotes: 1