我刚开始组装,我想创建一个简单的程序,将两个数字相加并打印结果
这是我到目前为止所拥有的:
.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(这是我感到困惑的地方)
如何指定在哪个寄存器上打印什么值?
另外,我如何完成此程序,当前在运行时,该程序导致分段错误?
答案 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,这将干净地退出程序。