2016-12-04 65 views
1

因此,我们开始在x86中做小事,但我根本无法掌握它。我们有这样的:在x86中遍历一个向量?

.Data 
    frequency DW 0, 260, 300, 330, 350, 390, 440, 500, 520, 590, 660, 700 

我来遍历它,似乎很简单,对我来说:

mov EAX, frequency 
    mov ECX, 0 // as a counter 

是不正确的,是吗?我正在考虑转移到EAX频率的地址,但对我来说似乎并不合适。
任何人都可以帮助我知道如何做一个简单的[if != 700]循环?
不要关心循环,只想知道如何将“频率”上的元素放入寄存器,然后继续获取下一个。

回答

0

你将不得不假设这些值连续存储在内存中。然后你得到一个指向第一个指针的地址(指针),然后通过每个元素的大小连续递增指针来遍历它们。要知道何时停止迭代(,即,对于循环终止条件),您可以使用计数器(因为您知道有一个常数为12的元素),或者您可以检查该值以查看是否它是700(然后你知道你在结尾)。

下面是一个使用计数器的例子:

mov ecx, 0     ; initialize counter 
    mov edx, OFFSET frequency ; get address of the first element 
DoLoop: 
    mov eax, DWORD PTR [edx] ; get value of the element 
    ...       ; do something with that value, now in the EAX register 
    inc ecx      ; increment counter by one 
    add edx, 2     ; increment pointer by size of an element 
    cmp ecx, 12     ; compare counter against 12 (total number of elements) 
    jl DoLoop     ; keep looping while less than 12 

有多种方式来写这个循环中,有些可能略超过上面的代码优化,但应该给你的想法。

如果你只想做一个简单的“如果x = 700!”循环,那么很简单:

cmp X, 700  ; where X is some register or memory location that you want to test 
jne BranchLabel ; where 'BranchLabel' is the label to jump to if X != 700 

一般来说,在x86上,你会使用CMP instruction做一个条件分支设置标志,然后是a Jcc instruction实际上是分支(其中cc是指定如何测试标志的条件代码)。

但是,您不必使用CMP指令。有为数众多的设置标志等指令,包括TEST和几乎所有的算术和逐位指令(如ADDSUBXOR等)。如果标志已经设置,那么你可以做的直接使用Jcc。没有必要进行冗余比较!

+2

由于您将指针增加2以到达下一个元素,因此实际读取* word *而不是* dword *可能是个好主意。 –

+0

这是一个好主意还是只是一个有效主意取决于你的具体目标体系结构。在许多情况下,在现代处理器上,这实际上会更快。但是你是对的,如果我读了一个字大小的值,它肯定会更清晰。 –

0

你是对的第一个。

mov EAX, frequency获取第一个元素的地址。
mov dx, [eax]从数组中获取元素。
add eax, 2移动到下一个元素。