Loops in Assembly Language - loops

Suppose A={1,2,3,4} and B={2,3,4,5} be two arrays. How can we initialize them by using loops? And how can we add corresponding elements of these arrays and store them into 3rd array by using loops? My assembler is masm615.
include irvine32.inc
.data
word ayyay1 5 dup(?)
word ayyay2 5 dup(?)
.code
main proc
top:
----------
----------
loop top
call dumpregs
exit
main endp
end main

Untested but generally guiding:
include irvine32.inc
.data
word ayyay1 5 dup(?)
word ayyay2 5 dup(?)
.code
main proc
lea edi, [ayyay1]
lea esi, [ayyay2]
mov ax, 1
mov bx, 2
mov cx, 4
top:
mov word [edi],ax
mov word [esi],bx
inc ax
inc bx
add edi,2 ; add to point to next word location
add esi,2 ; add to point to next word location
loop top
call dumpregs
exit
main endp
end main

Related

how do I swap the elements of 2 arrays of different types of the same length?

Not sure if I need a third array to temporarily store values in order to swap contents of arrayA and arrayB. I am a student learning assembly for the first time so please keep it simple.
.386
.model flat,stdcall ; memory system
.stack 4096 ; declare stack memory size 4kb
ExitProcess proto,dwExitCode:dword
.data
arrayA byte 01d, 04d, 02d ; 8bits
arrayB word 02d, 05d, 05d ; 16bits
.code
main proc
mov EAX, 0
mov EBX, 0
mov ECX, 3
mov EDX, 0
L1:
movzx bx, arrayA[ebx]
mov ax, arrayB[ebx]
xchg arrayA[ebx], al
xchg arrayB[ebx], bx
inc ebx
loop L1
invoke ExitProcess,0
main endp
end main

How can I print the contents of an array?

I'm trying to print the contents of an array by using assembly language as below.
I could compile the code, but I could not run it.
How should I fix the code to print the contents of an array?
TITLE arrayFill_example (arrayFill_ex.asm)
INCLUDE Irvine32.inc
.data
count = 5
array DWORD count DUP(?)
arraySize = ($ - array) / 4
.code
; saves the general-purpose registers, retrieves the parameters, and fills the array
ArrayFill PROC
push ebp
mov ebp,esp
pushad ; save registers
mov esi,[ebp+12] ; offset of array
mov ecx,[ebp+8] ; array length
cmp ecx,0 ; ECX == 0?
je L2 ; yes: skip over loop
L1:
mov eax,10000h ; get random 0-FFFFh
call RandomRange ; from the link library
mov [esi],ax ; insert value in array
add esi,TYPE WORD ; move to next element
loop L1
L2: popad ; restore registers
pop ebp
ret 8 ; clean up the stack
ArrayFill ENDP
main PROC
push OFFSET array ; passed by reference
push count ; passed by value
call ArrayFill
; for showing array contents
mov eax, 0
mov esi, array
mov ecx, arraySize
L1:
mov eax, array[esi * TYPE array]
call WriteInt
call Crlf
add esi, 4
loop L1
exit
main ENDP
END main
Specifically this part is not working for me...
; for showing array contents
mov eax, 0
mov esi, array
mov ecx, arraySize
L1:
mov eax, array[esi * TYPE array]
call WriteInt
call Crlf
add esi, 4
loop L1
Problem 1
array DWORD count DUP(?)
With this definition the array contains dwords. But your program just fills the array with words using:
mov [esi],ax ; insert value in array
add esi,TYPE WORD ; move to next element
Better write:
mov [esi], eax ; insert value in array
add esi, 4 ; move to next element
Problem 2
mov esi, array
...
mov eax, array[esi * TYPE array]
These lines are redundantly referring to the array. That's adding a pointer to a pointer, giving the wrong address! (Or actually, mov esi, array loaded the first element, not the address, because that's how MASM syntax works.)
mov esi, OFFSET array gives you the address in esi. From there, [esi] is the first element, array[esi] is similar to C array[ (intptr_t)array ] (but just a byte offset without scaling by the element size). The resulting address is unlikely to be valid.
Just use one or the other, indexing with small integers, or a pointer increment. Getting a pointer into a register is usually good, as in:
mov esi, OFFSET array
mov ecx, arraySize
L1:
mov eax, [esi]
call WriteInt
call Crlf
add esi, 4
loop L1

Assembly x86, looping and replace values in an array

Hey I need to make a program that loops through an array (1,2,3,4,5,6,7,8,9,10) and exchanges the element ‘i’ with element ‘i+5’ when ‘i' is under 4 When the program ends, the new array has the following values 6,7,8,9,10,1,2,3,4,5
and right now I have it looping through the array
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
WriteDec PROTO
Crlf PROTO
DumpRegs PROTO
.data
arrayB WORD 1,2,3,4,5,6,7,8,9,10
.code
main proc
mov eax,0
mov edi,OFFSET arrayB ; address of arrayB
mov ecx,LENGTHOF arrayB ; loop counter
mov ax,0 ; zero the accumulator
L1:
mov ax,[edi] ; mov current edi value from array into ax
xchg arrayB, ax ;change the current ax register with the value in arrayB
add edi,TYPE arrayB ; point to next integer
loop L1
call DumpRegs
call WriteDec
call crlf
invoke ExitProcess,0
main endp
end main
But Im having trouble actually a) telling when the loop is under 4, and b) replacing the values correctly. Any help would be greatly appreciated
Edit: I do know I can use "cmp" to compare the ecx register
Your task description is inconsistent; you say the array should be 6,7,8,9,10,1,2,3,4,5 at the end, and that calls for exchanging all elements with index under 5 (elements 0 to 4), not under 4.
The LOOP command (which is not a good idea, but that's beside the point) uses ECX as an implicit counter. If ECX is nonzero, it decrements and jumps to the label, if it's zero, it doesn't. So you're looping for exactly LENGTHOF arrayB times; that's wrong, you want to loop for half that.
Also, the XCHG command is wrong. The destination for the exchange is not at arrayB, it's at the current index + 5. You figure out how to fix that.
Also, once you exchange ax with the index+5'th element, you still need to write the retrieved value of the index+5'th element back into the index'th position.
You are using edi to point to the elements of the array and store them in ax, one solution will be to use esi to point to the element+5 and store it in bx, then move bx into edi and move ax into esi (by the way, the loop should repeat half-array-length times) :
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
WriteDec PROTO
Crlf PROTO
DumpRegs PROTO
.data
arrayB WORD 1,2,3,4,5,6,7,8,9,10
.code
main proc
;mov eax,0 ;◄■■ UNNECESSARY.
mov edi,OFFSET arrayB ; address of arrayB
mov ecx,5 ;◄■■ 10 ÷ 2 ("when ‘i' is under 4").
;mov ax,0 ;◄■■ UNNECESSARY.
L1:
mov ax,[edi] ; mov current edi value from array into ax
mov esi,edi
add esi,TYPE arrayB * 5 ;◄■■ ELEMENT "I+5".
mov bx,[esi] ;◄■■ BX = "I+5".
mov [edi],bx ;◄■■ EXCHANGE ONE REGISTER.
mov [esi],ax ;◄■■ EXCHANGE THE OTHER REGISTER.
add edi,TYPE arrayB ; point to next integer
loop L1
;----------------------------------------------
mov edi, OFFSET arrayB
mov ecx, LENGTHOF arrayB
DISPLAY_ARRAY:
xor eax, eax
mov ax, [edi]
call WriteDec
add edi,TYPE arrayB ; point to next integer
loop DISPLAY_ARRAY
;----------------------------------------------
call DumpRegs
call WriteDec
call crlf
invoke ExitProcess,0
main endp
end main
Edited the answer to add loop to display the array elements.

How do I loop through a string and store it into an array in NASM?

(total newbie to NASM struggling to learn)
I've put the 1st command line argument into register eax. It can be a string between 1-20 lowercase characters.
I now want to loop through this string, copying one character at a time into a byte array A in the program's memory and storing the length of the string N in memory too. At this point in the program I've checked that the string is a legal input and is fine length-wise and case-wise.
This is a rough structure (?) that doesn't seem to be working:
section .bss ; uninitialized data
N resd 1 ; length of string
A resb 1 ; byte array A
section .text
asm_main:
// legal input checking code
mov edx, 0
loop2:
mov al, [eax+edx]
mov [A+edx],al
inc edx
cmp al, 0
jz done_loop2
jmp loop2
done_loop2:
mov [N], edx
call print_int
mov eax, A
call print_string
// code for jumps to errors and end of main
(I'm only printing the size and string to check if the loops works correctly)
I'm getting unexpected outputs: for eg
input "hello" gives me
-6193920
hxETmcxbt=Se6o=Eaco/oa
Any help would be super appreciated, thank you! :)
I'll give you an example:
global asm_main
SECTION .data
global x
mystring: db "stackoverflow",0
mystringl: equ $-mystring
array: TIMES mystringl dd 0
SECTION .text
asm_main:
enter 0,0
pusha
mov ecx, 0 ; counter
looper:
cmp byte[mystring+ecx], 0x0 ; check for end of string
je exit
mov eax, 0 ; empty eax
mov al, byte[mystring+ecx] ; move string position into al
mov byte[array+ecx], al ; write into memory
push eax
mov eax, 0
mov al, byte[array+ecx]
call print_char
call print_nl
pop eax
add ecx, 1
jmp looper
exit:
If you need any help, feel free to message me.

How to move and display array values from one to another in Assembly Language?

I am trying to move the values in Array1 to Array2, and then display them. I have been working on this and could not figure it out at all. Would anyone please help me? Thanks
INCLUDE Irvine32.inc
INCLUDE macros.inc
.data
Array1 DWord 2,4,6,8,10
Array2 DWord 5 Dup(0)
.code
main PROC
mov edx, OFFSET Array1
mov esi, OFFSET Array2
mov ecx, LENGTHOF Array1
mov eax, 0
Call Dumpregs
Call Dumpregs
L1:
mWrite "Hello"
Call CRLF
Loop L1
Call Dumpregs
L2:
mov eax, [edx]
mov [esi], eax
add esi, 4
add edx, 4
Loop L2
exit
main ENDP
END main
Your L2 loop cannot produce the desired result since the preceding code wiped ECX clean (You used loop L1). To copy the array you need to re-initialize ECX. Also it's best to setup the pointers EDX and ESI close to this L2 loop because perhaps there is a risk of them being modified by all those preceding (macro)calls!
mov edx, OFFSET Array1
mov esi, OFFSET Array2
mov ecx,5
L2:
mov eax,[edx]
mov [esi],eax
add esi, 4
add edx, 4
loop L2

Resources