如何检查汇编语言(ASM)中的“数组长度”,

时间:2011-01-31 15:20:03

标签: assembly

我刚开始学习汇编语言。在java中,如果我们有一个Array,我们总是可以使用array.length来获取它的长度。在集会中有这样的事吗?如果是的话,有人可以在这里指导我吗?

修改

我很抱歉,我知道程序集没有数组,我试图简化一些事情。

我的意思是,如果我有一个变量

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

鉴于DB可以包含任意数量的元素,我如何检查它包含的总变量?

像java这样的东西,使用int数组来存储这个

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

我们可以 data.length 来查找元素的总金额。

8 个答案:

答案 0 :(得分:12)

回答这个问题的最好方法是使用C示例。在C中,有两种方法可以跟踪数组的长度:

  1. 您存储一个变量,告诉您制作数组的时间。
  2. 你做了什么字符串做什么,并将最后一个元素作为0.然后,你可以实现一个“字符串”长度函数,它循环遍历数组,直到它找到零。
  3. 对于第一个示例,根据您正在使用的汇编程序,您可能可以使用一些技巧。例如,在nasm中你可以这样做:

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

    如您所见,我们使用equ运算符来获取nasm来计算当前地址与msg的起点之间的差异,该差异应等于其长度。或者,您可以将数字写为数字。

    对于第二种情况,您可以轻松编写一个小函数来执行此操作。粗略地说,如果你:

    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
    

    请注意,我没有测试过。这只是为了给你一个想法。

    编辑我在Linux上测试了x86_64版本,使用rdi作为param1,传入int arr[10] = {1,2,3,4,5,6,7,8,9,0};。按预期返回9。请注意,在Linux上,mystrlen之前的下划线是不必要的。

答案 1 :(得分:7)

汇编比Java低得多。除其他外,这意味着没有“阵列”这样的东西。至少在您熟悉的安全Java形式中。

与数组相同的是分配一块内存,并将其视为一个数组。但是,您必须自己管理长度,因为您拥有的只是包含数据的大块内存。如果你想存储任何元数据,比如长度,你必须自己做。

您在Java中了解它们的数组包含长度等元数据,并进行边界检查。这些都是你必须要做的事情,只有他们隐藏它才能让你不必担心这些事情。

我建议你看看下面的内容,介绍如何在程序集中创建和使用等同于数组的内容:

答案 2 :(得分:2)

汇编中没有数组(据我所知)。如果您愿意,您可以自由地发明数组的工作原理。

如果您正在阅读编译器生成的程序集,那么您将不得不具体询问该编译器。

这样做的一种方法是允许数组的第一个字节存储每个元素的长度。另一种方法是null终止数组(这通常是字符串的维护方式)。

答案 3 :(得分:1)

答案 4 :(得分:1)

您可以使用以下程序(ATT汇编语法)确定数组中的元素数:

.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)

组装并链接程序:

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

结果是3,如预期的那样:

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

答案 5 :(得分:0)

MOV EAX,LENGTHOF数据

返回数组变量中的项数。

答案 6 :(得分:0)

我认为这会对你有帮助....

。数据

num db 2,4,6,8,10

.CODE

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

输出= 5

答案 7 :(得分:0)

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

在上面的代码中'a'是一个默认有6个元素的数组'a'将指向数组的第一个元素,'n'将在数组之后初始化。所以值'n-a'将对应于我们存储在n中的数组的长度。 不要初始化a和n之间的其他变量。这可能会给你错误的结果。