什么是汇编语言
约 543 个字 72 行代码 预计阅读时间 4 分钟
汇编语言总括
机器语言由 01 串组成,我们不可能直接通过输入 01 串来进行计算机操作,但是计算机也无法理解人类语言,因此才需要介于人类语言和机器语言之间的计算机语言。
称越接近人类语言的计算机语言越高级,那么计算机语言可分为高级语言、中级语言和低级语言三类。比如 BASIC,Pascal,Fortran 等都属于高级语言,C语言属于中级语言,而汇编语言则属于低级语言。
汇编语言的英文名称是 assembly language ,简称 ASM
不同类型的 CPU 的机器语言各不相同,故不同类型的 CPU 对应的汇编语言也各不相同,比如内置 M1 芯片的苹果电脑和内置 Intel 芯片的PC机,它们的汇编语言是不一样的。
另外,汇编语言还和操作系统有关系,因为汇编语言不像C语言一样具有标准库函数,程序要做到输入输出必然要调用操作系统的资源,而不同操作系统提供给用户的接口是不一样的。
- DOS 下的汇编语言要进行输入输出时需要调用
int 21h
进行中断 - Windows 下的汇编语言要进行输入输出时需要调用系统函数的 API
- Linux 系统下的汇编语言要进行输入输出则需要调用
int 80h
进行中断
由于DOS和Windows都是基于Intel CPU的,二者汇编语言有很多相似之处
现代操作系统对用户程序权限进行了限制,导致无法执行 cli,sti,int 等特权指令,因此本课程选用DOS操作系统下的 8086 汇编语言进行讲解。
第一个汇编语言程序
| data segment
s db "Hello,world!", 0Dh, 0Ah,'$' ; db: define bytes
data ends
code segment
assume cs:code, ds:data
main:
mov ax, seg s ; 等效于 mov ax, data
mov ds, ax
mov ah, 9
mov dx, offset s
int 21h ; 输出字符串 DS:DX -> '$'-terminated string
mov ah, 4Ch
int 21h
code ends
end main
|
程序输出看不到的话就使用管道 ./hello.exe > output.txt
。不过更推荐使用如下中断查看:
| mov ah, 1
int 21h ; 敲任意键继续
|
只使用代码段在屏幕上输出 Hello, world! :
| code segment
assume cs:code, ds:code
main:
push cs
pop ds ; DS=CS
mov ah, 9
mov dx, offset hi
int 21h
mov ah, 4Ch
int 21h
hi db 'Hello,world!', 0Dh, 0Ah, '$'
code ends
end main
|
一个 Windows 下的汇编语言程序,作用为计算 1 到 100 的和并输出
| .386 ;说明要用到32位寄存器 eax 等
.model flat, stdcall
option casemap :none
include include\windows.inc
include include\kernel32.inc
include include\user32.inc
includelib lib\kernel32.lib
includelib lib\user32.lib
.data
result db 100 dup(0); dup:duplicate重复
;char result[100]={0};
format db "%d",0; db:define byte字节类型
; char format[3]="%d"; "%d",0 相当于C语言的 "%d\0"
prompt db "The result",0
.code
main: ; 标号
mov eax, 0; eax:extended ax
mov ebx, 1
again: ; again 是 label,可作为跳转指令或者 call 的目标地址
add eax, ebx; eax=0+1+2+3
add ebx, 1 ; ebx=4
cmp ebx, 100; cmp:compare
jbe again ; jbe:jump if below or equal
invoke wsprintf, offset result, offset format, eax
; windows系统内部的函数,对应C语言标准库函数 sprintf
; wsprintf(&result[0], &format[0], eax);
; 例如 char buf[100]; wsprintf(buf, "%d", 5050); 将 5050 以字符串形式保存在数组 buf 中("5050\0")
invoke MessageBox,0,offset result,offset prompt,0
; 也是windows系统内部的函数,
; MessageBox(0, &result[0], &prompt[0], 0);
; 作用为弹框输出,标题为 prompt ,正文为 result ,按钮式样为 0
; 第一个参数用来指定弹框的父窗口的编号,当为 0 时表示没有父窗口
; 为什么不直接弹 5050? 因为 MessageBox 只能弹字符串
ret
end main; 指定程序的起始执行点
; end后面的标号决定了程序刚开始
; 运行时的eip的值。
|
Comments: