Frederick

Welcome to my Alter Ego's site!

Feb 24, 2025 - 5 minute read - Comments

汇编语言

编辑:vim/edit

编译:masm

链接:link

将内存2000:0,2000:1,2000:2,2000:3单元中的数据送入al,bl,cl,dl中

mov ax,2000

mov ds,ax;段地址2000h送入ds

mov bx,0;偏移地址0送入bx

mov al,[bx];ds:bx单元中的数据送入al
mov ax,2000

mov ds,ax;段地址2000h送入ds

mov al,ds:[0]

比较

mov al,[0];将常量0送入al中

mov al,ds:[0];(al)=((ds)*16+0)

mov al,ds:[bx];(al)=((ds)*16+(bx))

mov al,ds:[bx];与上面相同

循环

assume cs:code

code segment

​    mov ax,0ffffh

​    mov ds,ax;初始化ds:bx指向ffff:0

​    mov bx,0;初始化累加寄存器dx,(dx)=0

​    mov cx,12;初始化循环计数寄存器

s:  mov al,[bx]

​    mov ah,0

​    add dx,ax;间接向dx中加上((ds)*16+(bx))的数值

​    inc bx

​    loop s

   

​    mov ax,4c00h

​    int 21h

code ends

end

复制

assume cs:code

code segment

​    mov bx,0;偏移位置从0开始

​    mov cx,12;循环12次



s:  mov ax,0fffh

​    mov ds,ax;(ds)=0ffffh

​    mov dl,[bx];(dl)=((ds)*16+(bx)),将ffff:bx中的数据送入dl

​    mov ax,0020h

​    mov ds,ax;(ds)=0020h

​    mov [bx],dl;((ds)*16+bx)=(dl),将dl的数据送入0020:bx

​    inc bx;偏移位置加1

​    loop s

​    mov ax,4c00h

​    int 21h

code ends

end  

代码段中使用栈

assume cs:codesg

codesg segment

​     dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

​    dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;用dw定义16个字型数据,在程序加载后,将取得16个字的内存空间,存放16个数据,在后面的程序中将这段空间当作栈来使用

start: mov ax,cs

​        mov ss,ax

​        mov sp,30h

​       mov bx,0

​       mov cx,8

​     s:push cs:[bx]

​       add bx,2

​       loop s;将代码0-15单元中的8个字型数据依次入栈

​       mov bx,0

​       mov cx,8

​    s0:pop cs:[bx]

​       add bx,2

​       loop s0;出栈8个字型数据到代码段0-15单元

​       mov ax,4c00h

​       int 21h

codesg ends

end start;指明程序的入口在start处

初始状态下栈为空,所以ss:sp要指向栈底

将数据,代码,栈放入不同的段

QA:CPU如何知道stack放栈,data放数据?

mov ax,stack

mov ss,ax

mov sp,20h

设置ss指向stack,设置ss:sp指向stack:20

大小写转换问题

思路:大写ASCII码的第5位为0,小写字母的第5位为1

assume cs:codesg,ds:datasg
datasg segment
    db 'Basic'
    db 'iNfOrMaTiOn'
datasg ends
codesg segment
 start:mov ax,datasg
       mov ds,ax;设置ds指向daatsg
       mov bx,0;设置(bx)=0,ds:bx指向‘Basic’的第一个字母
       mov cx,5;设置循环次数5,因为‘Basic’有5个字母
     s:mov al,[bx];将ASCII码从ds:bx所指向的单元中取出
       and al,11011111B;将al中的ASCII码的第5位置为0,变为大写字母
       mov [bx],al;将转变后的ASCII码写回原单元
       inc bx
       loop s
       mov bx,5
       mov cx,11
    s0:mov al,[bx]
       or al,00100000B;将第5位置变为1
       mov [bx],al
       inc bx
       loop s0
       
       mov ax,4c00h
       int 21h
       
codesg ends
end start

[bx]一个内存单元

[bx+idata]表示一个内存单元

下面三个指令相同

  • mov ax,[bx+200]
  • mov ax,200[bx]
  • mov ax,[bx],200

下面两个指令相同

  • mov ax,[bx+si]
  • mov ax,[bx] [si]

(ax)=((ds)*16+(bx)+(si))

idata是常量,bx,si是变量

reg表示一个寄存器,sreg表示一个段寄存器

关注机器指令处理的数据在什么地方

mov bx,[0];内存,ds:0单元

mov bx,ax;CPU内部,ax寄存器

mov bx,1;CPU内部,指令缓存器

段地址(SA)和偏移地址(EA)

  • mov ax,ds:[bp]

(ax)=(ds)*16+(bp)

SA=(ds),EA=(bp)

X ptr指明内存单元的长度,X再汇编指令中可以为word或byte

例如mov word ptr ds:[0],1 指明了指令访问的内存单元是一个字单元

db字节型 dw字型 dd双字型数据

如dd 100

dup重复

dw (重复次数) dump (数据)

如db 3 dup (0) ,即db 0,0,0

db 3 dup(0,1,2),即db 0,1,2,0,1,2,0,1,2

转移指令的原理

start:mov ax,0

      mov bx,0

      jmp short s

      add ax,1

    s:inc

REVIEW:1.从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;2.(IP)=(IP)+所读取指令长度,从而指向下一条指令;3.执行指令,转到1,重复过程

  • CS= ,IP= CS:IP指向EB 03(jump short s的机器码)
  • 读取指令码EB 03进入指令缓冲器
  • IP=IP+所读取指令长度(2),指向add ax,1
  • CPU执行指令缓冲器中的指令EB 03(重点,如果EB 03没有对IP修改的话,应该执行add ax,1)
  • 执行后,IP=000BH,CS:IP指向inc ax

jmp word ptr 内存单元地址(段内转移)

jmp dword ptr 内存单元地址(段间转移)

jcxz相当于if((cx)==0)jump short 标号;

loop相当于(cx)–;if((cx)!=0)jump short 标号;

jump short s的转移范围是-128~127

offset

CPU执行ret指令,修改IP,pop IP

(IP)=((ss)*16+(sp))

(sp)=(sp)+2

CPU执行retf指令,修改CS和IP,POP IP,POP CS

(IP)=((ss)*16+(sp))

(sp)=(sp)+2

(IP)=((ss)*16+(sp))

(sp)=(sp)+2

CPU执行call指令,将CS和IP压入栈,转移,pump IP ;jmp near ptr标号

(sp)-=2

((ss)*16+(sp))=(IP)

IP+=16位位移

call far ptr 相当于push CS; push IP; jmp far ptr

mov ax,6;call ax将6存入ax,调用地址6处的函数

mul做乘法,要么都是16位要么都是8位

mul byte ptr ds:[0]

(ax)=(al)*((ds)*16+0)

ZF标志:零标志位。结果为0,ZF=1(逻辑为真),结果为1,ZF=0

PF标志:奇偶标志位,bit位个数是否为偶数

SF标志:符号标志位,非负,sf=1

CF标志:进位标志符,

cmp ax,bx即比较ax-bx

je等于则转移

jne

jb低于则转移below

jnb不低于则转移

ja高于则转移above

jna不高于则转移

逆向核心原理 nssctf逆向题

comments powered by Disqus