nasm随笔

nasm 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'
  inc bx
  mov byte ptr ds:[bx],1
  inc bx
  mov byte ptr ds:[bx],0x6dh ;'s'
  inc bx
  mov byte ptr ds:[bx],2
  inc bx
  mov byte ptr ds:[bx],0x73h ;'m'
  inc bx
  mov byte ptr ds:[bx],3
  jmp $ ;死循环
code ends
end
;    mov cx,10000
;  s:dec cx
;    loop s
;    mov ax,4c00h
;    int 21h

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 

win

nasm -f win32 %1
gcc %1 -o 1.exe -O3

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      ; 计算消息的长度
section .text			;指定代码段

global _start			;在链接时,程序从此入口处开始

_start:				;程序入口
   mov eax, 0x4		;系统调用号为4,对应write系统调用
   mov ebx, 0x1		;文件描述符为1,对应标准输出
   mov ecx, message	;输出的字符串地址
   mov edx, len	;字符串长度
   int 0x80			;调用系统中断,执行write系统调用

   mov eax, 0x1		;系统调用号为1,对应exit系统调用
   xor ebx, ebx		;返回值为0
   int 0x80			;调用系统中断,执行exit系统调用

section .data			;指定数据段
   message db "Hello World", 0xA	;输出的字符串
   len equ $-message		;字符串长度,使用equ定义
posted @ 2023-06-30 21:44  huh&uh  阅读(36)  评论(0)    收藏  举报