masm X86
assume cs:code
code segment
org 100h
mov ax,0xb800h
mov ds,ax
mov bx,0
mov byte ptr ds:[bx],0x61h ;'a'
add bx,2
mov byte ptr ds:[bx],0x6dh ;'s'
add bx,2
mov byte ptr ds:[bx],0x73h ;'m'
jmp $ ;死循环
code ends
end
section .data
message db 'This is a debug message', 10
len equ $ - message
section .text
global _start
_start:
mov eax, 4 ; 设置系统调用号
mov ebx, 1 ; 设置文件描述符为标准输出
mov ecx, message ; 设置要输出的消息的内存地址
mov edx, len ; 设置要输出的消息的大小
int 0x80
bash
nasm -f elf32 program.asm -o program.o
ld -m elf_i386 program.o -o program
./program
分析x64和x86
x64:
section .data
message_start:
db 'This is a debug message', 10;10是‘\n’
len equ $ - message_start
section .text
global _start
_start:
mov eax, 4 ; 设置系统调用号
mov ebx, 1 ; 设置文件描述符为标准输出
mov ecx, message_start ; 设置要输出的消息的内存地址
mov edx, len ; 设置要输出的消息的大小
int 0x80 ; 触发系统调用
/*
在第一条指令中,eax寄存器存储了系统调用号,这告诉操作系统要执行什么样的系统调用。在这个例子中,使用了系统调用号4,代表write系统调用。
在第二条指令中,ebx寄存器存储了文件描述符(fd),用于指示要向哪个流写入数据。在这个例子中,将它设置为1,即标准输出。这意味着要将输出写入控制台。
在第三条指令中,ecx寄存器存储了要输出的数据(即消息)的地址。它指向数据在内存中的位置。
在第四条指令中,edx寄存器存储了要输出的数据的大小(即消息的长度)。
接下来,使用'int 0x80'指令触发一个中断,使操作系统内核根据存储在eax中的系统调用号来调用相应的系统调用(即write系统调用)。操作系统内核在这个例子中将读取ebx寄存器中存储的文件描述符、ecx寄存器中存储的数据的地址和edx寄存器中存储的数据大小,并将数据输出到标准输出流中。
因此,这四个寄存器是用于将write系统调用所需的参数传递给操作系统内核的,使它可以将数据输出到控制台。
*/
x86:
mov ax, 4 ; 设置系统调用号
mov bx, 1 ; 设置文件描述符为标准输出
mov cx, message_start ; 设置要输出的消息的内存地址
mov dx, len ; 设置要输出的消息的大小
mov ds, cx ; 将message_start所在的段地址加载到DS寄存器
mov ah, 09h ; 设置为DOS的输出服务
int 21h ; 调用DOS系统中断,输出字符串
mov ah, 4Ch ; 设置为DOS系统退出服务
int 21h ; 调用DOS系统中断,程序退出
message_start db 'Hello World!', 0Dh, 0Ah, '$' ; 要输出的消息
len EQU $-message_start ; 计算消息的长度
标签:输出,调用,mov,start,设置,message,随笔,nasm
From: https://www.cnblogs.com/userhhh/p/17517884.html