Skip to content

第1讲:课程介绍与第一个汇编程序


一、课程设置

总评成绩:

  • 期末考试 40%
  • 平时作业 30%
  • 2 次小测 30%

学习目的:

  • 深入理解其他计算机语言
  • 学会 debug
  • 可以调试没有源代码的 exe 程序
  • 逆向工程:把机器语言代码转换成源代码,读懂没有源代码的 exe 程序,提取程序中的算法
  • 软件破解与保护
  • 黑客攻防

Mac 如何配置环境 (Apple Silicon)

其他配置参考白洪欢老师个人网页 cc.zju.edu.cn/bhh


二、第一个程序:1 + 2

先看 C 语言版本(1.c):

c
#include <stdio.h>
main()
{
   int a, b;
   a = 1;
   b = 2;
   a = a + b;
}

汇编版本(1.asm):

asm
code SEGMENT          ; 代码段的开始
assume cs:code
main:                 ; main 是一个标号(label), 用来表示跳转的目标地址
    mov ax, 1
    mov bx, 2
    add ax, bx
    mov ah, 4ch
    int 21h
code ENDS
end main
  • MOV eax, 0x00x0 是 0 的 16 进制表示,也就是 0。MOV 就是 move,把后面的值赋给前面的变量。
  • add ax, bx — ax = ax + bx

在 DOSBox 中运行:

bash
tasm 1.asm          # 编译
tlink 1.obj         # 链接
1.exe               # 运行

运行 td 1.exe 可以 debug,按 F8 下一步,按 Alt+X 退出。

程序退出代码

asm
mov ah, 4ch
int 21h

表示正常终止当前程序,并返回 DOS 系统


三、最简 if-else(老师第 2 周 2.asm)

C 语言:

c
#include <stdio.h>
main()
{
   int a=2, b=3, c;
   if(a > b)
      c = a;
   else
      c = b;
}

汇编:

asm
code segment
assume cs:code
main:
   mov ax, 2
   mov bx, 3
   cmp ax, bx
   jg ax_is_bigger    ; jg: jump if greater
bx_is_bigger:
   mov cx, bx
   jmp done           ; goto done
ax_is_bigger:
   mov cx, ax
done:   
code ends
end main

四、三个数取最大值(老师第 2 周 3.asm)

C 语言:

c
#include <stdio.h>
main()
{
   int a=1, b=2, c=3, d;
   if(a > b)
      if(a > c)
         d = a;
      else
         d = c;
   else
      if(b > c)
         d = b;
      else
         d = c;
}

汇编:

asm
code segment
assume cs:code
main:
   mov ax, 1
   mov bx, 2
   mov cx, 3
   cmp ax, bx
   jg ax_is_bigger_than_bx
   cmp bx, cx
   jg bx_is_bigger_than_cx
   mov dx, cx
   jmp done
bx_is_bigger_than_cx:
   mov dx, bx
   jmp done
ax_is_bigger_than_bx:  
   cmp ax, cx
   jg ax_is_bigger_than_cx
   mov dx, cx
   jmp done
ax_is_bigger_than_cx:
   mov dx, ax
done:   
code ends
end main

五、while 循环求 1+2+3(老师第 2 周 4.asm)

C 语言:

c
#include <stdio.h>
main()
{
   int a=1, b=0;
   while(a <= 3)
   {
      b = b + a;
      a = a + 1;
   }
}

汇编:

asm
code segment
assume cs:code
main:
   mov ax, 1
   mov bx, 0
again:   
   cmp ax, 3
   jg done
   add bx, ax
   add ax, 1
   jmp again
done:   
code ends
end main

六、while 循环求 3+2+1(老师第 2 周 5.asm)

C 语言:

c
#include <stdio.h>
main()
{
   int a=3, b=0;
   while(a > 0)
   {
      b = b + a;
      a = a - 1;
   }
}

汇编:

asm
code segment
assume cs:code
main:
   mov ax, 3
   mov bx, 0
again:   
   cmp ax, 0
   jle done            ; jle: jump if less or equal
   add bx, ax
   sub ax, 1           ; ax = ax - 1, sub: subtract
   jmp again
done:   
code ends
end main

七、双层循环求 1! + 2! + 3!(老师第 2 周 6.asm)

C 语言:

c
#include <stdio.h>
main()
{
   int a, b, c, d=0;
   for(a=1; a<=3; a++)
   {
      c = 1;
      for(b=1; b<=a; b++)
      {
         c = c * b;
      }
      d = d + c;
   }
}

汇编(使用 .386 的 imul cx, bx 指令):

asm
.386                   ; 表示本程序可能会用到 386 指令
code segment use16     ; use16 表示在编译时所有涉及的地址仍使用16位而非32位
assume cs:code
main:
   mov dx, 0
   mov ax, 1
again:   
   cmp ax, 3
   jg done
   mov cx, 1
   mov bx, 1
   next:   
      cmp bx, ax
      jg do_sum
      imul cx, bx     ; cx = cx * bx
      add bx, 1
      jmp next
do_sum:
   add dx, cx
   add ax, 1
   jmp again
done:
   code ends
end main

八、常用命令速查

bash
cd <path>       # change directory 改变当前目录
td <file>       # turbo debug 启动调试
tasm file.asm   # 编译
tlink file.obj  # 链接
file.exe        # 运行