首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环组件x86

循环组件x86
EN

Stack Overflow用户
提问于 2014-11-02 07:22:07
回答 2查看 721关注 0票数 0

我是汇编(x86 ATT语法)的初学者。我正在做一个赋值,我必须遍历二维数组的每个索引,并找到1的个数。这个方法接受二维整数数组,int w,int h。我如何实现从0到w的循环,并使用循环指令弹出。我知道如何使用jmp指令来做这件事,但是循环只会给我错误/segFaults。这是我用一个跳转语句的尝试,它起作用了。如何使用循环指令转换内循环?

代码语言:javascript
复制
pushl   %ebp
movl    %esp, %ebp

movl    $0, -4(%ebp)
movl    $0, -8(%ebp)
movl    $0, -12(%ebp)
movl    $0, -4(%ebp) #outside loop
jmp .L10

.L14:  #Inner Loop
movl    $0, -8(%ebp)
jmp .L11

.L13:
movl    -4(%ebp), %eax
leal    0(,%eax,4), %edx
movl    8(%ebp), %eax
addl    %edx, %eax
movl    (%eax), %eax
movl    -8(%ebp), %edx
sall    $2, %edx
addl    %edx, %eax
movl    (%eax), %eax
cmpl    $1, %eax
jne .L12
addl    $1, -12(%ebp)

.L12:
addl    $1, -8(%ebp)
.L11: #check inner loop
movl    -8(%ebp), %eax
cmpl    12(%ebp), %eax
jl  .L13 
addl    $1, -4(%ebp)

.L10: #check outside loop
movl    -4(%ebp), %eax
cmpl    16(%ebp), %eax
jl  .L14
movl    -12(%ebp), %eax

leave
ret
EN

回答 2

Stack Overflow用户

发布于 2014-11-02 07:34:51

一般来说,使用loop没有任何优势,除了可能更小的代码。它通常速度较慢,灵活性较差,因此不推荐使用。

也就是说,如果您仍然想使用它,您应该知道它使用ecx寄存器进行倒数到零。因此,您需要重新构造代码以适应这种情况。在您的例子中,这意味着用w的值加载ecx并让它倒计时。在索引期间,您还需要应用-1的偏移量,因为当前的循环变量从0w-1,而ecx将从w向下到1 (包括)。

此外,loop指令在循环体之后使用,也就是说,它实现了一个do-while循环。若要在计数为零时跳过循环体,可以使用配套指令JECXZ

票数 3
EN

Stack Overflow用户

发布于 2014-11-02 17:35:50

您可以同时使用lodsl (默认情况下向上移动%esi )和loop (向下移动%ecx )。我不确定它是否比gcc从c生成的代码效率更高,但它看起来更漂亮。

我在这里所做的并没有准确地回答您的问题--而不是将loop用于内部循环,我假设整个数组都是连续存储的,然后只需要担心一个循环。在我的机器上从c编译时,它是连续存储的,但我不确定您是否应该依赖它。希望我所做的工作足以让您理解looplodsl是如何工作的,并且您可以修改代码,以便只在内部循环中使用它们。

代码语言:javascript
复制
.data
x:
    .long 6
y:
    .long 5
array:
    .long 1,1,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1 

.text
.global _start
_start:
    # set up for procedure call
    push x  
    push y
    push $array
    # call and cleanup
    call cnt
    add $0xc, %esp
    # put result in %ebx and finish up 
    #(echo $? gives value in bash if <256)  
    mov %eax, %ebx
    mov $1, %eax
    int $0x80

# %ebx will hold the count of 1s
# %ecx will hold the number of elements to check
# %esi will hold the address of the first element
# Assumes elements are stored contiguously in memory
cnt:
    # do progogue
    enter $0, $1
    # set %ebx to 0
    xorl %ebx, %ebx
    # grab x and y parameters from stack and
    # multiply together to get the number of elements
    # in the array
    movl 0x10(%ebp), %eax   
    movl 0xc(%ebp), %ecx
    mul %ecx
    movl %eax, %ecx
    # get address of first element in array
    movl 0x8(%ebp), %esi 
getel:
    # grab the value at the address in %esi and increment %esi
    # it is put in %eax
    lodsl
    # if the value in %eax is 1, increment %ebx
    cmpl $1, %eax
    jne ne
    incl %ebx
ne:
    # decrement %ecx and if it is greater than 0, keep going
    loop getel
    # %ecx is zero so we are done.  Put the count in %eax
    movl %ebx, %eax
    # do epilogue
    leave
    ret

没有所有的评论,它真的更漂亮。

代码语言:javascript
复制
.data
x:
    .long 6
y:
    .long 5
array:
    .long 1,1,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1 

.text
.global _start
_start:
    push x  
    push y
    push $array
    call cnt
    add $0xc, %esp
    mov %eax, %ebx
    mov $1, %eax
    int $0x80

cnt:
    enter $0, $1
    xorl %ebx, %ebx
    movl 0x10(%ebp), %eax   
    movl 0xc(%ebp), %ecx
    mul %ecx
    movl %eax, %ecx
    movl 0x8(%ebp), %esi 
getel:
    lodsl
    cmpl $1, %eax
    jne ne
    incl %ebx
ne:
    loop getel
    movl %ebx, %eax
    leave
    ret
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26694319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档