开发者

How to check an "array's length" in Assembly Language (ASM),

I just started learning Assembly language. In java, if we have an Array, we can always use array.length to get its length. Is there such a thing in assembly? If so, can someone please guide me here?

Edit:

My apologies, I know assembly doesn't have arrays, I was 开发者_运维知识库trying to simplify things.

What I meant was, if for example I have a variable

data DB 1,2,3,5,7,8,9,10

Given that DB can contain any amount of elements, how can i check the total variable it contains?

Something like java, where use int array to store this

int data = {1,2,3,4,57,8,9,10};

We can just data.length to find the total amountt of elements.


The best way to answer this is to use C examples. In C, there are two ways of keeping track of the length of an array:

  1. You store a variable telling you how long you made the array.
  2. You do what strings do and have the last element as 0. Then, you can implement a "string" length function that loops over the array until it finds zero.

For the first example, depending on what assembler you're using, you might be able to use some tricks. For example, in nasm you can do this:

SECTION .data       

msg:    db "Hello World",10,0  ; the 0-terminated string.
len:    equ $-msg              ; "$" means current address.

As you can see, we use the equ operator to get nasm to calculate the difference between the current address and the start of msg which should equal its length. Alternatively, you could just write the length in there as a digit.

For the second case, you could easily write a small function to do it. Roughly speaking, if you:

SECTION .text

global _mystrlen

_mystrlen:

    push    ebp        ; conform to C calling conventions.
    mov     ebp, esp

    xor     eax, eax
    lea     ecx, [esp+8]   ; load the start of the array into ecx
    jecxz   end            ; jump if [ecx] is zero.

loop:
    add     eax, 1     ; could use inc eax as well. 
    add     ecx, 4     ; always increment by (sizeof(int)). Change as appropriate
    mov     edx, [ecx] ; load ecx
    cmp     edx, 0     ; compare with zerp
    je      end        ; if ecx is zero, we're done.
    jmp     loop       ; if ecx isn't zero, loop until it is.

end:
    leave              ; restore stack frame
    ret                ; return. eax is retval

Note that I haven't tested that. It's just to give you an idea.

Edit I've tested the x86_64 version on Linux, using rdi as param1, passing in int arr[10] = {1,2,3,4,5,6,7,8,9,0};. Returns 9 as expected. Note that on Linux the underscore preceding mystrlen is unnecessary.


Assembly is a lot more lowlevel than Java. This, among other things, means there's no such thing as an "array". At least in the safe Java form in which you know it.

What would be equivalent to an array is allocating a chunk of memory, and treat it as an array. The length and such you'll have to manage yourself, though, as all you have is a chunk of memory containing your data. If you want to store any metadata, such as length, you'll have to do that yourself.

Arrays as you know them in Java contain metadata such as length, and do bounds checking. These do the same thing you'll have to do, only they hide it so you won't have to worry about those things.

I suggest you take a look at the following for an introduction on how one would commonly create and use what is equivalent to an array in assembly:

  • The Art of Assembly Language Programming - Arrays


There is no such thing as an array in assembly (as far as I know). You are free to invent how an array works if you wish.

If you're reading the assembly generated by a compiler then you will have to ask specifically about that compiler.

One way of doing this would be to allow the first byte of the array to store the length of each element. Another way would be to null terminate the array (this is generally how strings are maintained).


You could use the following program (ATT assembly syntax) to determine the number of elements in an array:

.section .data
array:
    .long 3,5,8             # create an array of 32-bit integers
    arrsize = . - array     # in bytes (assemble-time constant, not stored)
    arrlen = (. - array)/4  # in dwords

.section .text
.globl _start
_start:

    mov   $arrlen, %edi
    mov   $60, %eax      # __NR_exit  in asm/unistd_64.h
    syscall              # sys_exit(arrlen)

Assemble and link the program:

gcc -c array.s && ld array.o
  #or
gcc -nostdlib -static array.s

The result is 3, as expected:

>./a.out            # run program in shell
>echo $?            # check the exit status (which is the number of elements in the array)
3


I found this thread very enlightening on the subject: Asm Examples: Finding the size of an array with different data types


a db 10h,20h,30h,40h,50h,60h
n db n-a

in the above code 'a' is an array having 6 elements by default 'a' will point to the first element of the array and 'n' will be initialised just after the array. so value 'n-a' will correspond to the length of the array which we are storing in n. don't initialise other variables in between a and n. This might give you wrong results.


MOV EAX,LENGTHOF data

Returns the number of items in array variable.


I think this will help you....

.data

num db 2,4,6,8,10

.code

main proc
mov eax,0 ; initialize with zero
mov ax,lengthof num 

output=5

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜