使用YASM编程

来源:互联网 发布:蔡司编程视频教程 编辑:程序博客网 时间:2024/06/16 20:56

我们一般实现C语言的 汉诺塔的时候,代码类似下面

;;void hanno(a,b,c,n);{;       if(n==1);       {;          printf("%c %c\n",a,c);;          return ;;       };       hanno(a,c,b,n-1);       hanno(a,b,c,1);       hanno(b,a,c,n-1);}

在汇编语言中处理比较麻烦的是参数的处理和局部变量,全局变量的处理。
这里将每个参数都定义为宏,每个宏都代表[ebp+8] [ebp+12]
然后我们就可以使用这些宏了。
未来我们用一个宏来定义这些参数,然后就能很方便的使用。
1 这里并没有将原来的Invoke 宏实现加载进来
2 这里也没有将 EBP 内容保存恢复等封装
3 这里也没有将局部变量保存和恢复封装。
我们展示一下基本的递归的实现和变量的使用.
栈的内容
| |
|新的栈底|
| | ————— 表示变量区域,变量区域必须保留
| | | 否则会被其他的函数调用覆盖
| |—————
| ebp |
|返回地址|
|第一个参数|
|第二个参数|
|第三个参数|
|…|

而ebp指向前面的ebp … 当前ebp可以理解为一个队列的头,如果有一个新的函数调用那么就会将现在的ebp插入到队列头上
这个队列结构类似
struct stack_ebp{
stack_ebp next*;
void* addr;
void* param[0]; // 这个是参数列表
}
下面的汇编就使用了上面的知识 。
下面这段代码是编译 .asm 文件,并且声称对应的obj pdb exe 文件

rem build_asm.batrem build_asm fiborem 编译和链接vsyasm -f win32 -g cv8 -o %1.obj %1.asmlink /entry:start /DEBUG /PDB:%1.pdb /subsystem:console /debug /machine:x86 /out:%1.exe /release /verbose:lib /libpath:C:\masm32\lib kernel32.lib user32.lib %1.obj msvcrt.lib  
bits 32[section .data]format: db "%c -> %c",0x0a,0[section .text]global startglobal hannoextern _printfextern _scanfstart:jmp codevar_a : db 'a'var_b : db 'b'var_c : db 'c'[section .data]input_num_format: db "%d",0var_n : dd 0promot_string: db "input a num:",0[section .text]code:    push promot_string    call _printf    add esp,4    push var_n    push input_num_format    call _scanf    add esp,8    movsx eax,BYTE [var_n]    push eax    movsx eax,BYTE [var_c]    push eax    movsx eax,BYTE [var_b]    push eax    movsx eax,BYTE [var_a]    push eax    call hanno    add esp,16ret[section .text];输入 a,b,c,n ; a - 字母; b - 字母; c - 字母; n - 多少个盘子;;;a - [ebp+8];b - [ebp+0x0c];c - [ebp+0x10];n - [ebp+0x14]hanno:%define hanno_a DWORD [ebp+8]%define hanno_b DWORD [ebp+12]%define hanno_c DWORD [ebp+16]%define hanno_n DWORD [ebp+20]    push ebp    mov ebp,esp    cmp hanno_n,1    jz is_one    mov eax,hanno_n    dec eax    push eax    push hanno_b    push hanno_c    push hanno_a    call hanno    add esp,16    push 1    push hanno_c    push hanno_b    push hanno_a    call hanno    add esp,16    mov eax,hanno_n    dec eax    push eax    push hanno_c    push hanno_a    push hanno_b    call hanno    add esp,16    pop ebp    retis_one:    push hanno_c    push hanno_a    push format    call _printf    add esp,12    pop ebp    ret
原创粉丝点击