汇编:语法速通

文章目录

HelloWorld

代码

复制代码
section  .text		;代码段起始
   global _start     ;导出_start符号到目标文件符号表,给链接器使用
   
_start:              ;入口地址
   mov   edx,len     ;长度立即数放入edx
   mov   ecx,msg     ;字符串地址放入ecx
   mov   ebx,1       ;准备使用stdout输出
   mov   eax,4       ;sys_write系统调用号
   int   0x80        ;触发软中断,内核根据eax调用sys_write,根据ebx写到stdout输出,内容为字符串地址后len长度的字节。
   
   mov   eax,1       ;内核返回后eax存放实际写入的字节数14,已经没用了,所以用1覆盖,准备调用sys_exit
   int   0x80        ;调内核终止进程

section  .data		;数据段起始
msg db 'Hello, world!', 0xa  ;声明msg变量,db表示define byte,按字节定义以下内容:字符串、0xa换行
len equ $ - msg     ;msg长度计算,等于地址之差

编译脚本

复制代码
#!/bin/bash

nasm -f elf hello.asm
ld -m elf_i386 -s -o hello hello.o
./hello

int 0x80 寄存器约定

寄存器 用途 对应参数
eax 系统调用号 4 = sys_write
ebx 第 1 个参数 文件描述符 fd
ecx 第 2 个参数 缓冲区地址 buf
edx 第 3 个参数 字节数 count

变量定义

伪指令 位数 典型用途
db 8 bit 字节串、ASCII 字符串
dw 16 bit 字、Unicode 字符
dd 32 bit 双字、32 位整数/地址
dq 64 bit 四字、64 位整数
dt 80 bit 扩展精度浮点(BCD)

equ用法

equ 是等值宏,类似C的 #define,在编译时原地替换为立即数,不占运行时内存。

如果想把 len 定义为变量,可以使用dd定义32位整数。

复制代码
len dd 14

代码段相应修改,表示取 len 内容放入edx。

复制代码
mov   edx,[len]

字符串数值比较

复制代码
section .text
   global _start         ;must be declared for using gcc

_start:                  ;tell linker entry point
   mov   ecx, [num1]    ;num1先放到ecx
   cmp   ecx, [num2]    ;比较num1>num2则跳转到check_third_num比较num1和num3,否则用num2放到ecx
   jg    check_third_num
   mov   ecx, [num2]
   
check_third_num:
   cmp   ecx, [num3]    ;比较ecx>num3则直接跳转到_exit,否则用num3放到ecx.
   jg    _exit
   mov   ecx, [num3]
   
_exit:
   mov   [largest], ecx    ;保证ecx中一定是最大值,mov到largest变量中。
   mov   ecx,msg    ;输出msg
   mov   edx, len
   mov   ebx,1  ;file descriptor (stdout)
   mov   eax,4  ;system call number (sys_write)
   int   0x80   ;call kernel
        
   mov   ecx,largest    ;输出最大值
   mov   edx, 2
   mov   ebx,1  ;file descriptor (stdout)
   mov   eax,4  ;system call number (sys_write)
   int   0x80   ;call kernel
    
   mov   eax, 1
   int   80h

section .data
   
   msg db "The largest digit is: ", 0xA,0xD 
   len equ $- msg 
   num1 dd 47
   num2 dd 22
   num3 dd 31

segment .bss
   largest resb 2  

循环打印0-9

复制代码
section .text
   global _start        ;must be declared for using gcc
        
_start:                 ;tell linker entry point
   mov ecx,10    ;循环次数
   mov eax, '0'    ;起始字符
        
l1:
   mov [num], eax
   mov eax, 4
   mov ebx, 1
   push ecx    ;循环计数器值入栈防止被破坏
        
   mov ecx, num    ;打印字符        
   mov edx, 1        
   int 0x80
        
   mov eax, [num]    ;取回打印后的字符
   sub eax, '0'    ;字符转数字'1' - '0' = 1
   inc eax        ;数字自增1
   add eax, '0'    ;数字转字符
   pop ecx    ;恢复循环计数器
   loop l1    ;ecx-- 不等于0时跳回l1(loop指令假定ecx包含循环计数值,直至减为0停止)
        
   mov eax,1             ;system call number (sys_exit)
   int 0x80              ;call kernel
section .bss
	num resb 1

求和函数(过程)

复制代码
section .text
   global _start        ;must be declared for using gcc
        
_start:                 ;tell linker entry point
   mov  ecx,'4'
   sub     ecx, '0'
        
   mov  edx, '5'
   sub     edx, '0'    ;字符转数字
        
   call    sum          ;调求和函数
   mov  [res], eax      ;结果写入内存
   
   mov  ecx, msg        ;打印消息        
   mov  edx, len
   mov  ebx,1           ;file descriptor (stdout)
   mov  eax,4           ;system call number (sys_write)
   int  0x80            ;call kernel
        
   mov  ecx, res        ;打印结果
   mov  edx, 1
   mov  ebx, 1          ;file descriptor (stdout)
   mov  eax, 4          ;system call number (sys_write)
   int  0x80            ;call kernel
        
   mov  eax,1           ;system call number (sys_exit)
   int  0x80            ;call kernel
sum:                    ;数字相加后转字符
   mov     eax, ecx
   add     eax, edx
   add     eax, '0'
   ret                  ;返回callee继续执行
        
section .data
msg db "The sum is:", 0xA,0xD 
len equ $- msg   

segment .bss
res resb 1

汇编的宏等价于复制粘贴代码块,区别于函数,宏没有call/ret过程,只在编译阶段展开。

语法为

复制代码
%macro macro_name  number_of_params    ;关键字 宏名 参数数量
<macro body>
%endmacro

示例

复制代码
; A macro with two parameters
; Implements the write system call
   %macro write_string 2    ;包装打印字符串的宏
      mov   eax, 4
      mov   ebx, 1
      mov   ecx, %1    ;第一个参数
      mov   edx, %2    ;第二个参数
      int   80h
   %endmacro
 
section .text
   global _start            ;must be declared for using gcc
        
_start:                     ;tell linker entry point
   write_string msg1, len1    ;宏名 第一个参数 第二个参数              
   write_string msg2, len2    
   write_string msg3, len3  
        
   mov eax,1                ;system call number (sys_exit)
   int 0x80                 ;call kernel

section .data
msg1 db 'Hello, programmers!',0xA,0xD   
len1 equ $ - msg1                       

msg2 db 'Welcome to the world of,', 0xA,0xD 
len2 equ $- msg2 

msg3 db 'Linux assembly programming! '
len3 equ $- msg3
相关推荐
rechol10 小时前
汇编与底层编程笔记
汇编·arm开发·笔记
CHANG_THE_WORLD1 天前
switch语句在汇编层面的几种优化方式 ,为什么能进行优化
汇编·算法·switch·汇编分析·switch case·switch case 汇编·switch case 语句
SundayBear2 天前
嵌入式进阶:C语言内联汇编
c语言·开发语言·汇编
CC-NX3 天前
32位汇编:实验5算数运算类指令使用
汇编·win32·算数运算
伐尘3 天前
【汇编】RAX,eax,ax,ah,al 关系
汇编
CHANG_THE_WORLD3 天前
c语言位运算 汇编代码分析
c语言·开发语言·汇编
CHANG_THE_WORLD3 天前
if条件语句 三目运算符 汇编分析
汇编·算法·条件语句·if 语句·汇编分析·条件语句汇编分析
CHANG_THE_WORLD5 天前
有符号数和无符号数的 汇编视角 区别
汇编
南飞测绘视界5 天前
【编号220】中国国内生产总值历史数据汇编1952-2021合订本(PDF扫描版)
汇编·pdf·年鉴
Ayanami_Reii7 天前
汇编和C语言结构
c语言·汇编·笔记