将两个数字相加

时间:2018-07-19 23:27:40

标签: c linux assembly cpu-registers

我刚开始组装,我想创建一个简单的程序,将两个数字相加并打印结果

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

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

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

第1行:我正在创建一个标签主体,链接器可以访问它

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

第3行:我开始定义main

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

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

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

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

如何指定在哪个寄存器上打印什么值?

另外,我如何完成此程序,当前在运行时,该程序导致分段错误?

1 个答案:

答案 0 :(得分:6)

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包含添加eax,ebx的结果,标签'fmt'是一个字符数组:“%d \ n \ 0”(%d格式,换行符,空终止符)。

在调用printf之后,您需要通过退出系统调用实际退出程序,否则(至少对我而言),即使在printf起作用之后,该程序也会在执行后出现段错误,并且您将看不到结果。

这两行:

mov    eax, 1
int    0x80

正在执行sys_exit系统调用,方法是将x86(1)上的退出顺序放入EAX中,然后调用中断0x80,这将干净地退出程序。