Initialize array to specific values in assembly (x86)
I want to initialize an array in an assembly with specific values. I tried to do this in the first loop, but got garbage in the arrays. Then I tried to do it manually and got the same junk. I want the array to repeat 0 1 2 for n times. Here is some sample code I've tried.
This is my attempt to fully load the array. The first value loads just fine. The second value, however, is loaded in junk when I check it in GDB.
sub esp, 260
mov [ebp - 12], dword -1
mov [ebp - 16], byte 0
mov [ebp - 17], byte 1
mov [ebp - 18], byte 2
mov [ebp - 19], byte 0
mov [ebp - 20], byte 1
mov [ebp - 21], byte 2
mov [ebp - 22], byte 0
mov [ebp - 23], byte 1
mov [ebp - 24], byte 2
mov [ebp - 25], byte 0
Here's my attempt at doing it automatically.
sub esp, 260
mov [ebp - 12], dword -1
again:
add [ebp - 12], dword 1
lea eax, [ebp - 16]
sub eax, [ebp - 12]
mov [eax], byte 0
add [ebp - 12], dword 1
lea eax, [ebp - 16]
sub eax, [ebp - 12]
mov [eax], byte 1
add [ebp - 12], dword 1
lea eax, [ebp - 16]
sub eax, [ebp - 12]
mov [eax], byte 2
cmp [ebp - 12], dword 255
jne again
jmp elsewhere
Using NASM, x86-32, Intel syntax.
EDIT: When I convert this code to store array values as DWORD instead of bytes, both methods work. Why is this?
source to share
With NASM, you can easily initialize duplicate data with a prefix times
. For example, to repeat the sequence "0 1 2" n times as indicated in your question, you could do something similar to the following:
section .data
my_array: times n db 0, 1, 2
Just replace n
the constant with the value you want. More information on the prefix times
can be found in the NASM Handbook .
source to share
This is what I got:
;ecx = how much values ;ds:edi = destination
function:
pushad ;push all 32bit registers to stack
xor eax,eax ;clear eax
function_loop:
push eax
mov ebx,0x00000003 ;we divide by 3
xor edx,edx ;clear edx
div ebx ;this stores the remainder of eax/0x03 in edx
mov DWORD [edi],edx ;move it to your array
pop eax ;we dont need the result of the division
inc eax
add edi,4 ;increment pointer 4 bytes because 4 bytes are one DWORD
loop function_loop ;loop til ecx is 0
popad ;pop all 32bit registers
ret
I wrote this out of my head, so please report it with a bug
but what you need to do is increment the register and do a modulo operation with 3 in an incremental register and then you have the pattern 0,1,2
just make sure you have enough free space to store all n values
source to share
This may trigger more ideas about the allocation of bytes or words on the stack.
You might want to create a library of personal functions or macros that you can use often, or find another library for% include.
You can interpret array data in bytes, dword, or other size in the same way as all data items are the same. You should always keep in mind the size of the array element (eg 1 vs 4 bytes ..). I will leave any alignment issues up to you to resolve.
section .data
_len equ 64
section .text
%macro mod 2
mov eax, %1
mov ebx, %2
xor edx, edx
div ebx ; div/mul are very slow; but ok for small loops
mov eax, edx ; return eax if you wish
%endmacro
global _start
_start:
nop
sub esp, _len ;
mov ecx, 1
L1:
mod ecx, 3 ; n mod 3
mov byte [esp+ecx], al
inc ecx
cmp ecx, _len ; array size
jb L1
add sp, _len
_exit:
mov eax, 1
mov ebx, 0
int 0x80
GDB x / 64d $ esp example using the following ....
(gdb)
0xffffd180: 0 1 2 0 1 2 0 1
0xffffd188: 2 0 1 2 0 1 2 0
0xffffd190: 1 2 0 1 2 0 1 2
0xffffd198: 0 1 2 0 1 2 0 1
0xffffd1a0: 2 0 1 2 0 1 2 0
0xffffd1a8: 1 2 0 1 2 0 1 2
0xffffd1b0: 0 1 2 0 1 2 0 1
0xffffd1b8: 2 0 1 2 0 1 0 0
31 v eax, 1
(gdb)
0xffffd180: 0 1 2 0 1 2 0 1
0xffffd188: 2 0 1 2 0 1 2 0
0xffffd190: 1 2 0 1 2 0 1 2
0xffffd198: 0 1 2 0 1 2 0 1
0xffffd1a0: 2 0 1 2 0 1 2 0
0xffffd1a8: 1 2 0 1 2 0 1 2
0xffffd1b0: 0 1 2 0 1 2 0 1
0xffffd1b8: 2 0 1 2 0 1 0 0
25 cx, 3 ; n mod 3
(gdb)
0xffffd180: 0 1 2 0 1 2 0 1
0xffffd188: 2 0 1 2 0 1 2 0
0xffffd190: 1 2 0 1 2 0 1 2
0xffffd198: 0 1 2 0 1 2 0 1
0xffffd1a0: 2 0 1 2 0 1 2 0
0xffffd1a8: 1 2 0 1 2 0 1 2
0xffffd1b0: 0 1 2 0 1 2 0 1
0xffffd1b8: 2 0 1 2 0 1 0 0
27 cx
(gdb)
0xffffd180: 0 1 2 0 1 2 0 1
0xffffd188: 2 0 1 2 0 1 2 0
0xffffd190: 1 2 0 1 2 0 1 2
0xffffd198: 0 1 2 0 1 2 0 1
0xffffd1a0: 2 0 1 2 0 1 2 0
0xffffd1a8: 1 2 0 1 2 0 1 2
0xffffd1b0: 0 1 2 0 1 2
0
source to share