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(这里是我感到困惑的地方)
如何指定打印寄存器的值?
另外,如何完成此程序,目前运行时,程序会导致分段错误?
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系统调用,这将彻底退出程序.
| 归档时间: |
|
| 查看次数: |
1675 次 |
| 最近记录: |