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"
Related
iam trying to write an assembly code 8086 i have two array X AND Y size 10 and i want to enter a number and check if its positive y will be 1 if negative it will be 0
but my code just displayed what i enter a number but i want it like this example .
example:
X : 2 -5 -7 8 -4 9 11 -12 90 -50
Y : 1 0 0 1 1 0 1 1 0 1 0
I wrote:
.MODEL SMALL
.DATA
x db 10 dup ("?")
y db 10 dup ("?")
.CODE
MOV AH,1
INT 21H
mov si,offset x
mov di,offset y
mov [si],al
cmp si,0
ja l1
jmp l2
l1 : mov al , 1
mov [di],al
jmp l3
l2 : mov ah , 0
mov y[di] , al
jmp l3
l3 :
MOV AH, 2
mov dl,al
INT 21H
cmp si,10
je l4
inc si
inc di
l4 :
.EXIT
END
The list of problems is long. Check out these comments and try to see why the error exists.
<<<< add label for a 10-time repeat
MOV AH,1
INT 21H
mov si,offset x <<<< move higher up for 1-time execution
mov di,offset y <<<< move higher up for 1-time execution
mov [si],al
cmp si,0 <<<< the byte to compare is in AL
ja l1 <<<< requires a SIGNED conditional, use JGE
jmp l2 <<<< reverse condition and drop this jump
l1 : mov al , 1
mov [di],al
jmp l3
l2 : mov ah , 0 <<<< should be AL
mov y[di] , al <<<< DI already refers to the y-array, use just [DI]
jmp l3 <<<< redundant
l3 :
MOV AH, 2
mov dl,al
INT 21H
cmp si,10 <<<< 10 is wrong
je l4
inc si <<<< move above checking iterator
inc di <<<< move above checking iterator
<<<< needs jumping back in order to repeat
l4 :
Next code, just like yours, inputs a single character from the keyboard and treats its ASCII code as the byte you want to store in the x array. For negative bytes you should input extended ASCII's. Use the Alt followed by a number up to 255.
.CODE
xor bx, bx
again:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
mov x[bx], al
mov ah, 255
shl ax, 1
not ah
mov y[bx], ah ; 1 for positive, 0 for negative
inc bx
cmp bx, 10
jb again
.EXIT
TL;DR: How to copy elements from one array to another (not all but some)?
I want to perform a sorting algorithm on some array, but so that I only sort odd or even numbers in it, depending on a flag. So my idea was to set a flag on either 0 or 1 and then I'd extract all the numbers that have to be sorted into another array and put -1 (as a marker) on the positions where those numbers were. After that I'd just insert the sorted numbers back into the original array, for example:
arr1: 5 8 2 4 13 9 14 10 9
arr2: 8 2 4 14 10
arr2 (sorted): 2 4 8 10 14
arr1 (without even numbers): 5 -1 -1 -1 13 9 -1 -1 9
arr1 (final): 5 2 4 8 13 9 10 14 9
Now while writing this in a higher language is rather trivial for me, doing it in assembly which I'm learning for a class isn't. The part where I sort the numbers works just fine, but the part that causes me problems is the one where I have to copy the numbers into another array. My main method looks like this:
section .data
arr dd 6,8,1,7,4,2,9,107,10,8,12,16,14,5
len equ ($-arr) / 4 - 1
section .bss
section .text
extern sort
global _start
_start:
mov r8, len
mov esi, arr ; esi points to the start of the array/top of it
call sort
mov rax, 60
mov rdi, 0
syscall
And the subroutine which will do the job (showing only the problematic part):
mov r9d, esi
.export:
mov eax, [r9d]
cdq
div dword [divider]
cmp edx, [flag]
je .add
.continue:
add r9d, 4 ; point to the next number
inc dword [i]
cmp r8d, [i]
jg .export
.add:
mov edi, [r9d]
mov dword [r9d], -1 ; put the number in the old array to -1
sub edi, 4
inc dword [lenNewArray] ; inc the total number of elements in new array
jmp .continue
Anyway what I want to accomplish is that I add an element that matches the condition to some location and then point rdi to that location, when I want to add another element I subtract -4 from rdi so it points to the lower location and put that element there, in the end I'd have rdi pointing to the last element which was extracted, is that possible to be done, and is it a bad way?
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
I am having problem on how exactly should i use loop to get the desire output in this program,
What i want to do is to take input any number from the user and then sort that number in descending order,
I tried my best here to explain every step of the code in the comment.
here is my code,
STSEG SEGMENT
DB 64 DUP(?)
STSEG ENDS
DTSEG SEGMENT
SNAME DB 24 DUP("$")
DTSEG ENDS
CDSEG SEGMENT
MAIN PROC
ASSUME CS:CDSEG, DS:DTSEG, SS:STSEG
MOV AX,DTSEG
MOV DS,AX
MOV ES, AX ;ES:DI
MOV DX, OFFSET STRNG1
MOV AH,09
INT 21H
XOR DX,DX
MOV BYTE PTR SNAME, 40
MOV DX, OFFSET SNAME
MOV AH, 0AH
INT 21H
PUSH DX ;Hold the input number in a stack until we clear the screen and set the cursor
; The clear screen and cursor position code is here which i didn't really mention.
;What we need to do now is to compare first number to each other number and store the greatest
of two on first position.
MOV BX,DX ;Copy un-sorted number to BX,
MOV AX,BX[1] ;the length of the number which is stored on the first position of the string
XOR AH,AH ;Empty AH
MOV CL,AL ;MOVE AL into CL for looping 6 times
SUB CL,1
MOV SI,02H ;the number is stored in string array from the 2nd position
;Suppose the input number is the following,
;[6][3][9][1][8][2][6]
;this is how it should work,
; Loop 6 times , CX = 6
[7][6][3][9][1][8][2][6] ; 7 is length of the number which is already copied in CX above.
; but we need 6 iterations this is why we subtract 1 from CL above.
; 6 > 3 ?
; Yes, then BX[SI] = 6 and BX[SI+1] = 3
; 6 > 9 ?
; NO, then BX[SI] = 9 and BX[SI+2] = 6
; 9 > 1
; Yes, then BX[SI] = 9 and BX[SI+3] = 1
; 9 > 8
; Yes, then BX[SI] = 9 and BX[SI+4] = 8
; 9 > 2
; Yes, then BX[SI] = 9 and BX[SI+5] = 2
; 9 > 6
; Yes, then BX[SI] = 9 and BX[SI+6] = 6
; After first iteration the incomplete sorted number is,
;[9][3][6][1][8][2][6]
;Similarly here i need to loop 5 times now by comparing the 2nd number which is a 3 with all ;the number after it and then loop 4 times then 3 times then two times and then 1 time.
L1:
;Loop 1 must iterate 6 time for the supposed input number,
;but i couldn't be able to write the proper code as i always get out of registers. kindly help me out
L2:
LOOP L2
Loop L1
Kindly help me with the nested loop where i've stucked.
The loop instruction uses the cx register.
So you must either preserve cx for the outer loop with e.g. push cx (before L2:) and pop cx (after loop L2):
mov cx,5
L1:
push cx
mov cx,6
L2:
. . . do stuff inner
loop L2
pop cx
. . . do stuff outer
loop L1
or remember that loop is roughly equal to dec cx jnz, so do e.g.
mov dx,5
L1:
mov cx,6
L2:
... do stuf inner
loop L2
.. do stuff outer
dec dx
jnz L1
Possible off-by-one errors are intended and meant as an exercise for the reader :-)
I have a programming assignment to run through and set the background and text of all the possible combinations. I am using a predefined function called SetTextColor which basically sets the values like this:
mov eax, white + (blue * 16)
Essentially this sets the text white and the background blue (to set the background you multiply by 16). Basically the combination is 16 X 16 = 256
TITLE BACKGROUND COLORS (main.asm)
; Description: T
; Author: Chad Peppers
; Revision date: June 21, 2012
INCLUDE Irvine32.inc
.data
COUNT = 16
COUNT2 = 16
LCOUNT DWORD ?
val1 DWORD 0
val2 DWORD 0
.code
main PROC
mov ecx, COUNT
L1:
mov LCOUNT, ecx
mov ecx, COUNT2
L2:
mov eax, val1 + (val2 * 16)
call SetTextColor
inc val2
Loop L2
mov ecx, LCOUNT
Loop L1
call DumpRegs
exit
main ENDP
END main
Basically I am doing a nested loop. My thinking is that I simply do a 1 * (1 * 16) then inc the value in a nested loop until 1 * (16 * 16). I am getting the error below
I am getting the error A2026: constant expected
I imagine the error you are getting is at this line:
mov eax, val1 + (val2 * 16)
You just can't do that. If you intend to multiply val2 by 16 and then add val1 to the result, then you need to implement it step by step (you may come across addressing in the form of a+b*c but a and c need to be registers and b can only be 2, 4 or 8, not 16). Try replacing this line with something like this:
mov eax, val2
imul eax, 16
add aex, val1