Created
May 21, 2014 17:06
-
-
Save FlatMapIO/ab3c833c87b06800c919 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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