在装配中添加两个数字

问题描述 投票:0回答:2

我刚刚开始使用汇编,我想创建一个简单的程序来添加两个数字并打印结果

这是我到目前为止所拥有的:

.globl main
   .type main, @function
main:
   movl $14, %eax
   movl $10, %ebx
   add %eax, %ebx
call printf

根据我的理解,这是逐行发生的事情

第 1 行:我正在创建一个可由链接器访问的标签 main

第 2 行:我正在为函数指定 main 标签的类型

第 3 行:我开始定义 main

第4行:我将数值14存储到通用寄存器eax中

第5行:我将数值10存储到通用寄存器ebx中

第 6 行:我将 eax 和 ebx 处的值相加,并将结果存储在 ebx 中

第 7 行:我调用函数 printf(这是我感到困惑的地方)

如何指定打印寄存器的值?

另外,我如何完成这个程序?当前运行时,程序会导致分段错误。

c linux assembly x86
2个回答
12
投票
SECTION .data

    extern printf
    global main

fmt:
    db "%d", 10, 0

SECTION .text

main:
    mov     eax, 14
    mov     ebx, 10
    add     eax, ebx

    push    eax
    push    fmt
    call    printf

    mov     eax, 1
    int     0x80

不幸的是,我不知道您使用的是哪个编译器/汇编器,而且我不熟悉 at&t 语法,因此我为您提供了一个适用于 Nasm 的 Intel 风格 x86 的工作示例。

$ nasm -f elf32 test.s -o test.o
$ gcc test.o -m32 -o test
$ ./test
24

为了使用 printf,您需要将其参数实际推入堆栈,我在这里以相反的顺序执行此操作(首先推入最后一个参数):

push    eax
push    fmt

EAX 包含 add eax, ebx 的结果,标签 'fmt' 是一个字符数组:“%d "(%d 格式、换行符、空终止符)。

调用 printf 后,您需要使用 exit 系统调用实际退出程序,否则(至少对我来说)程序将在 printf 之后出现段错误,即使它有效,您也看不到结果。

所以这两行:

mov    eax, 1
int    0x80

通过将 x86 上的退出序号 (1) 放入 EAX 来执行 sys_exit 系统调用,然后调用中断 0x80,这会干净地退出程序。


0
投票

你不能只存储 %eax 和 %ebx 的输出,然后打印出来,或者直接执行“call printf”add %eax, %ebx”吗?我是一个初学者,这是我的第一天,我刚刚有了好奇心

© www.soinside.com 2019 - 2024. All rights reserved.