I am new to assembly and was trying to work with an array. However, I was geting caught when try to compare the array value to a constant stored in a register.
From the following code I was expecting the program to jump after comparison because the value in the array seems to match the literal in esi. My code is as follows.
global _start
section .data
yay: db "It Worked!",0xA
array1: db 1, 2, 3, 4
section .bss
section .text
_start:
mov eax, [array1 + 1]
mov esi, 2
cmp eax, esi
je .equal
jmp _done
.equal:
mov eax, 4
mov ebx, 0
mov ecx, yay
mov edx, 11
int 0x80
jmp _done
_done:
mov eax, 1
mov ebx, 0
int 0x80
Any advice as to mistakes in my code are greatly appreciated too!
The reason your code is not properly loading the value located at the first index of your array into EAX
is because of what an array is in assembly. In assembly, when you define an "array" you are simply placing data into memory. While this might seem obvious, it also means that there is NOT a separator between elements (A "string" is also an array). This means that when you do MOV EAX, [ARRAY1 + 1]
without specifying the size of the operation, nasm looks at the context of the instruction to defer the size. Because you are using a 32-bit register, the size is defaulted to a DWORD
. This means that the instruction will load 32 bits (4 bytes) from your array starting at [ARRAY1 + 1]
. To prevent this, you need to specify the size of your operation as a byte by doing MOVZX EAX, BYTE [ARRAY1 + 1]
. You need to use MOVZX
to fill the rest of the register with zeros.
The first thing that sticks out to me about your code is the usage of JMP
right before the label you are jumping too. This is unnecessary because execution will just continue into a label. This is because labels are not "functions," rather just markers that represent memory addresses. They do not exist in the assembled program. Secondly, while not major, instead of doing MOV EAX, 0
, it is slightly faster to execute XOR EAX, EAX
. Finaly, you have an empty BSS
section, this is not needed for the linker and can just be left out (at least for ld).