Reputation: 133
Im a beginner at assembly and Im making a program that is going to take the value in a variable num
and seeing if that number is in an array, it will print "That number is in the array" if not it will print something else. But it always prints, "The number is not in the array". Why?
section .text
global _start
_start:
mov eax, [numArray]
mov ecx, 3 ;How many times Num will loop
Num:
cmp [num], eax ;compare num to eax
je inArray ;If equal go to inArray message
dec ecx ;decrement ecx
inc eax ;move to next element
jz notIn ;If counter = 0 and a match still has not been found goto notIn
jnz Num ;Else go back to Num
inArray: ;Print msg1
mov eax, 4
mov ebx, 1
mov ecx, msg1
mov edx, len1
int 0x80
jmp _exit
notIn: ;Print msg2
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, len2
int 0x80
jmp _exit
_exit: ;exit program
mov eax, 1
int 0x80
section .data
num db 1
numArray db 1, 2, 3
msg1 db 'That is in the array!'
len1 equ $-msg1
msg2 db 'That is not in the array'
len2 equ $-msg2
Upvotes: 0
Views: 709
Reputation: 1572
Some basic things:
mov eax, [data]
means, retrieve the contents indicated by the address data
and store them in eax
.
This instruction retrieves a 32-bit quantity, because you have specified a 32-bit destination.
If you want to retrieve just one Byte, you will need to specify an 8-bit destination:
mov al, [data]
Furthermore, if you want to load the address of a variable (a label), you simply write
mov rax, data
Confer point 5: Confusing value and address of a variable. For an address, a pointer, you almost always use a 64‑bit register (in 64‑bit mode), confer 10.5 Addresses and pointers in 64-bit mode.
lea rax, [data]
does effectively the same, but as you can see different notation, different instruction, thus different code.
You usually use string instructions for that kind of task. Unlike in high-level programming languages, “string” means any kind of continuous data, not just character strings.
global _start
bits 64
default rel
; ### constants ################################################
sys_exit: equ 1
; ### intialized data ##########################################
section .data
data:
db 42, -6, 13, -7, 99, 2
data_size: equ $ - data
; ### executable code section ##################################
section .text
_start:
xor ebx, ebx ; ebx ≔ 0
mov ecx, data_size ; exc ≔ count
mov rdi, data ; rdi ≔ @data
mov eax, 99 ; the number to find
repne scasb ; scan string Byte
; as it customary for program exit status: 0 means
; successful, and any non-zero value indicates an error
setnz bl ; bl ≔ ¬ZF
exit:
mov eax, sys_exit ; request number
int 0x80
; vim: set ft=nasm:
cld
(“forward” direction) has been omitted because the used ABI says it must be cleared upon process initialization (and function entry and return).
scasb
retrieves a Byte from the location indicated by the value in rdi
, compares it to the contents in al
, sets the ZF
according to the result, increments rdi
(depends on DF
) and decrements rcx
.
All of that in one instruction.
The repne
prefix simply means, while
the ZF is clear and ecx
has not hit 0
yet.
Upvotes: 1