linux - 简单的加法器不工作

标签 linux assembly

我用程序集制作了简单的参数加法器,但它不起作用

它总是返回 0

    .section .data
    .section .text
    .global _start
_start:
    call adder
    movl %eax,%ebx
    movl $1,%eax
    int $0x80
adder:
    pushl %ebp
    movl %esp,%ebp
    movl $0,%eax        #eax = return
    movl $1,%ebx        #ebx = index
    movl 8(%ebp),%ecx    #number of args
loop:
    cmpl %ebx,%ecx
    jg exit
    addl 8(%ebp,%ebx,4),%eax
    incl %ebx
    jmp loop
exit:
    movl %ebp,%esp
    popl %ebp
    ret

最佳答案

此代码存在一些问题,但您的方向是正确的。

1。循环条件

ebx >= ecx 时,您正在使用它来退出循环:

cmpl %ebx,%ecx
jg exit

语法相当困惑,但这实际上意味着“如果 ecx 大于 ebx 则退出”。将其更改为 jng exit 可解决此问题。

2。堆栈参数

您指的是带有 8(%ebp,%ebx,4) 的参数,但参数实际上是从 12(%ebp) 开始的。你是对的,你应该从索引 1 开始,因为索引 0 的参数只是程序的名称。

3。参数总是字符串

栈上的参数只是指向字符串的指针。 movl 12(%ebp),%eax 不会将命令行中的数字放入 eax。它只会在 eax 中放入一个内存地址,指向构成第一个参数的一系列字符。

要获得由字符串“123”表示的数字,您需要使用类似atoi 的函数对其进行解析。 .然后 atoi 将在 eax 中返回 123。

修复这些问题后,代码如下所示。我在每个更改的行旁边都添加了注释。

    .section .data
    .section .text
    .global _start
_start:
    call adder
    movl %eax,%ebx
    movl $1,%eax
    int $0x80
adder:
    pushl %ebp
    movl %esp,%ebp
    movl $0,%eax        #eax = return
    movl $1,%ebx        #ebx = index
    movl 8(%ebp),%ecx    #number of args
loop:
    cmpl %ebx,%ecx
    jng exit                # quit if ecx is not greater than ebx

    pushl %eax              # save registers on stack
    pushl %ecx              # because they will be destroyed soon

    pushl 12(%ebp,%ebx,4)   # push next argument pointer on stack
    call atoi               # invoke atoi, this destroys registers eax,ecx,edx
    add $4,%esp             # restore stack pointer

    mov %eax,%edx           # atoi returns the value in eax, save that to edx
    popl %ecx               # restore ecx from stack
    popl %eax               # restore eax from stack

    addl %edx,%eax          # add parsed number to accumulator

    incl %ebx
    jmp loop
exit:
    movl %ebp,%esp
    popl %ebp
    ret

程序现在似乎可以运行了:

$ gcc -nostartfiles test.S -m32 && ./a.out 1 2 3 4 5 ; echo $?
15

程序在其退出值中返回结果,这意味着它不能计数大于 255 :) 让程序使用 printf 将结果打印到标准输出可能会更好。

关于linux - 简单的加法器不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5427893/

相关文章:

assembly - 如何使用emu8086读取硬件输入

c - 是否可以将二进制文件加载到内存中并在Windows中执行

C包含十六进制常量的文件

c++ - 无法在 MIPS 中获得正确的输出

linux - bash:遍历进程输出并终止进程

linux - 通过保存虚拟设备删除 genymotion

linux - 在 Linux 中检测到 HDD 时如何得到通知

assembly - 条件跳转到注册

linux - 磁盘已满,但找不到哪个文件夹占用空间

linux - 无法在 LINUX 上安装 Fuchsia