我刚刚开始使用汇编,我想创建一个简单的程序来添加两个数字并打印结果
这是我到目前为止所拥有的:
.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(这是我感到困惑的地方)
如何指定打印寄存器的值?
另外,我如何完成这个程序?当前运行时,程序会导致分段错误。
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,这会干净地退出程序。
你不能只存储 %eax 和 %ebx 的输出,然后打印出来,或者直接执行“call printf”add %eax, %ebx”吗?我是一个初学者,这是我的第一天,我刚刚有了好奇心