在程序集中添加两个数字

Ste*_*mas 0 c linux assembly cpu-registers

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

这是我到目前为止:

.globl main
   .type main, @function
main:
   movl $14, %eax
   movl $10, %ebx
   add %eax, %ebx
call printf
Run Code Online (Sandbox Code Playgroud)

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

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

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

第3行:我开始对main进行定义

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

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

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

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

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

另外,如何完成此程序,目前运行时,程序会导致分段错误?

use*_*423 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
Run Code Online (Sandbox Code Playgroud)

不幸的是我不知道你正在使用哪个编译器/汇编器,而且我不熟悉at&t语法,所以我给了你一个英特尔风格x86 for Nasm的工作示例.

$ nasm -f elf32 test.s -o test.o
$ gcc test.o -m32 -o test
$ ./test
24
Run Code Online (Sandbox Code Playgroud)

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

push    eax
push    fmt
Run Code Online (Sandbox Code Playgroud)

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

在调用printf之后,您需要使用退出系统调用实际退出程序,否则(至少对我而言)程序将在printf之后进行段错误,即使它有效并且您将看不到结果.

所以这两行:

mov    eax, 1
int    0x80
Run Code Online (Sandbox Code Playgroud)

通过将x86(1)上的exit的序号放入EAX,然后调用中断0x80来执行sys_exit系统调用,这将彻底退出程序.

  • 通过将程序的返回代码放入 eax 中,例如“mov eax, 0”,然后从 main 退出,可以从程序正常退出。与“ret”。这就是为什么在 c 中我们使用 `return 0;` 来退出我们的程序。 (2认同)