Skip to content

Instantly share code, notes, and snippets.

@FlatMapIO
Created May 21, 2014 17:06
Show Gist options
  • Save FlatMapIO/ab3c833c87b06800c919 to your computer and use it in GitHub Desktop.
Save FlatMapIO/ab3c833c87b06800c919 to your computer and use it in GitHub Desktop.
; NASM 快速入门
; 原文: http://www.ibm.com/developerworks/cn/linux/l-gas-nasm.html
; nasm: http://www.nasm.us/
; Text segment, 是处理器开始执行代码的地方
section .text
global _start ; 让一个符号对链接器可见
; Program entry
_start:
mov eax, 1 ; 传送 1 到 eax
mov ebx, 2 ; 返回值
; 调用系统
; 它请求系统一个服务, 服务编码放在 EAX 中
; EAX 如果是1, 代表 Linux 的 exit 调用
; 80h 代表 hex
int 80h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data
; 变量名 内存分配 变量值
var1 dd 40 ; 32 位
var2 dw 20 ; 16 位
var3 db 30 ; 8 位
section .text
global _start
_start:
mov ecx, [var1] ; []代表访问 var1 地址的内存值
cmp ecx, [var2]
jg check_third_var
mov ecx, [var2]
check_third_var:
cmp ecx, [var3]
jg _exit
mov ecx. [var3]
_exit:
mov eax, 1
mov edx, ecx
int 80h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data
prompt_str db 'Enter you name'
$ 是地址游标, 记录当前指令地址
STR_SIZE equ $ - prompt_str ;
greet_str db 'hello'
; equ 表达式赋值给变量的指令
GSTR_SIZE equ $ - greet_str
; block storage segment -- 未初始化内存
; BSS 部分中保留的内存在程序启动时初始化为零
; BSS 部分中的对象只有一个名称和大小, 没有值
; BSS 部分中声明的变量并不实际占用空间
section .bss
; resb 在 BSS 节中分配字节 (byte-8)
; resw 在 BSS 节分配字 (word-16)
; resd 在 BSS 节分配双字 (dword-32)
buff resb 32 ; 保留 32 字节在内存中
; 实现写系统调用
; 2 是参数个数
; %1 代表第一个参数
; %2 代表第二个参数 ...
%macro write 2
mov eax, 4
mov ebx, 1
mov ecx, %1
mov edx, %2
int 80h
%endmacro
; 实现读系统调用
%macro read 2
mov eax, 3
mov ebx, 8
mov ecx, %1
mov edx, %2
int 80h
#endmacro
section .text
global _start
_start:
write prompt_str, STR_SIZE
read buff, 32
; 在 eax 中读返回值长度
push eax
; 打印 hello
write greet_str, GSTR_SIZE
pop edx
; edx = 长度通过 read 返回
_exit:
mov eax, 1
mov ebx, 8
int 80h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 演示了函数、各种内存寻址方案、堆栈和库函数的使用方法
; 对包含 10 个数字的数组进行排序
; 并使用外部 C 库函数 puts 和 printf 输出未排序数组和已排序数组的完整内容
section .data
array db
85, 10, 87, 1, 4, 27
ARRAY_SIZE equ $-array
array_fm db= %d, 0
usort_str db "unsorted array:", 0
sort_str db "sorted array:", 0
newline db 10, 0
section .text
extern puts
global _start
_start:
push usort_str
; puts(*) 就是打印*位置的 char
call puts
; call 后, esp 代表栈顶,[esp+4]
; 堆栈中压入一个变量会让堆栈指针移动一个双字, 因此 esp+=4
add esp, 4
; 压入3个参数
push ARRAY_SIZE
push array
push array_fmt
call print_array10
add esp, 12
push ARRAY_SIZE
push array
call sort_rontine20
; 调整栈指针
add esp, 8
push sort_str
call puts
add esp, 4
push ARRAY_SIZE
push array
push array_fmt
call print_array10
add esp, 12
jmp _exit
extern printf
print_array10:
push ebp
mov ebp, esp
sub esb, 4
mov edx, [ebp+8]
mov ebx, [ebp+12]
mov ecx, [ebp+16]
mov esi, 0
push_loop:
mov [ebp-4], ecx
mov edx, [ebp+8]
xor eax, eax
mov al, byte [ebx+esi]
push eax
push edx
call printf
add esp, 8
mov ecx, [ebp-4]
inc esi
loop push_loop
push newline
call printf
add esp, 4
mov esp, ebp
pop ebp
ret
sort_rontine20:
push ebp
mov ebp, esp
; 分配一个字的空间大小的数组
sub esp, 4
; 得到数据地址
mov ebx, [ebp+8]
; 存储数据大小
mov ecx, [ebp+12]
dec ecx
; 准备跳出循环
xor esi, esi
outer_loop:
; 存储小索引
mov [ebp-4], esi
mov edi, esi
inc edi
inner_loop:
cmp edi, ARRAY_SIZE
jge swap_vars
xor al, al
mov edx, [ebp-4]
mov al, byte [ebx+edx]
cmp byte [ebx + edi], al
jge check_next
mov [ebp-4], edi
check_next:
inc edi
jmp inner_loop
swap_vars:
mov edi, [ebp-4]
mov dl, byte [ebx+edi]
mov al, byte [ebx+esi]
mov byte [ebx+esi], dl
mov byte [ebx+edl], al
inc esi
loop outer_loop
mov esp, ebp
pop ebp
ret
_exit:
mov eax, 1
mov ebx, 0
int 80h
TODO
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment