Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 我的简单汇编程序中的无限循环_Loops_Assembly_X86 - Fatal编程技术网

Loops 我的简单汇编程序中的无限循环

Loops 我的简单汇编程序中的无限循环,loops,assembly,x86,Loops,Assembly,X86,我正在学习组装中的循环和跳跃,我试着做一个简单的循环。我希望调用printf命令10次。我已将计数器变量设置为1。我还将%edx设置为1,然后在每次迭代中递增它。如果它等于10,那么我们应该退出循环。但现在循环是无限的。我已经用gdb进行了调试,%edx似乎在printf函数中被覆盖。这就是为什么我将%edx推到堆栈中,然后在printf调用后将其弹出,但它不起作用。我错过了什么 .section .data output: .asciz "Value is %d\n" val1:

我正在学习组装中的循环和跳跃,我试着做一个简单的循环。我希望调用
printf
命令10次。我已将
计数器
变量设置为1。我还将
%edx
设置为1,然后在每次迭代中递增它。如果它等于10,那么我们应该退出循环。但现在循环是无限的。我已经用
gdb
进行了调试,
%edx
似乎在
printf
函数中被覆盖。这就是为什么我
将%edx
推到堆栈中,然后
printf
调用后将其弹出,但它不起作用。我错过了什么

.section .data
output:
    .asciz "Value is %d\n"
val1:
    .int 123
counter:
    .int 1
.section .text
.globl _start
_start:
    nop
    movl counter, %edx   # start at 1
gohere:
    movl val1, %ebx      # move value 123 to %ebx
    pushl %edx           # push %edx to stack
    pushl %ebx           # push %ebx to stack 
    pushl $output
    call printf          # call printf
    popl %edx            # pop %edx value
    inc %edx
    cmp $10, %edx        # if %edx is less than 10...
    jl gohere            # ... go to gohere, otherwise exit

    movl $0, %ebx
    movl $1, %eax
    int $0x80

您在最后一次按下时按下了
output
,因此第一次弹出将弹出
output
。这是堆栈,这是后进先出。在您的代码中,弹出后,
输出
将进入
edx
。 要解决此问题,请在popl edx之前放置两个POP:

popl output
popl ebx

printf()是一个使用cdecl调用约定的C函数。这需要你弹出你推的参数。因此,popl%edx实际上没有恢复edx寄存器值,堆栈不平衡。添加两个pop。哦,我添加了
popl%edx
的次数与我将值推送到堆栈中的次数一样多,而且成功了!请看我在上面代码中所做的编辑。但像这样多次流行价值观似乎有点丑陋。没有更简单的方法吗?我回滚了您的编辑,因为如果您编辑问题以包含答案中给出的解决方案(例如添加到
popl
说明),那么对于未来的读者来说,答案将变得毫无意义。因此,不应编辑问题的基本内容(如代码)以匹配答案。是的,几秒钟前我注意到了这一点。:-)正如我在上面的评论中所问的:难道没有比在推送值时多次弹出值更简单的方法了吗?我不能直接指向堆栈中的位置以将值弹出到%edx吗?当然可以,它是程序集,可以指向内存中的任何位置。但它比两个POP更复杂(应该指向堆栈基后的2个字节)。数据结构原则说不要这样做,
输出
似乎是13个字节(13个字符),而
val1
是4个字节的整数。如果我做了
-17(%esp)
我应该能够直接将-17(%esp)的值设置为%edx,但是我想我计算字节数的方法是错误的,因为它不起作用。是的,但是“output”的地址(偏移量)只有4个字节。请在通话后尝试添加$8,%esp
,然后您应该能够按预期添加%edx。(我不擅长at&T stntax,所以可能把事情搞砸了)