汇编学习笔记

本文是作者学习汇编语言过程中的笔记,详细记录了从基本指令到复杂操作的逐步理解,涵盖了汇编语言的基础概念、数据处理和程序控制等方面的内容,旨在帮助读者建立对底层计算机操作的直观认识。
摘要由CSDN通过智能技术生成
#include "test01.h"
int main() {
	//F9增删断点/直接点击左边空位
	//F5执行到下一个断点
	//F10逐行执行不进函数
	//F11逐行执行进入函数
	int a = 20000;
	int* p = &a;
	printf("0x%p\n", p);
	//十进制的20000转成十六进制是4e20,int占四字节空间
	//可以看到连续四个字节是20 4e 00 00 ,显然20在低位,4e在高位,得知win32是小端模式!
	char* cp = (char*)p;
	printf("%02x,%02x,%02x,%02x\n", cp[0], cp[1], cp[2], cp[3]);
	return 0;
	/*
		8086CPU寄存器:
		CS/DS/SS/ES是段寄存器,分别是code segment/data segment/stack segment/extract segment(暂不知有何用)
		AX/BX/CX/DX是通用寄存器,AX可以分成AH与AL,16位(四个16进制数字表示)分成两个8位,溢进后会把进位寄存器置1
		IP与CS搭配使用,IP就是偏移地址,注意CS与IP不能MOV,只可jump 2AE3:3就是跳到2AE*16+3
		SI是源数据指针,DI是目的地址指针,两个都是与DS配合,注意DS必须由寄存器转入
		SP与SS配合,SP就是偏移地址,得到的就是栈地址
		BP是基地址寄存器,一般在访问数组或是有固定偏移量的记录时用于存放基地址,就是说在用到数组时使用
		FR是各种标志位:
		OF overflow flag 溢出标志 操作数超出机器能表示的范围表示溢出,溢出时为1.
		SF sign Flag 符号标志 记录运算结果的符号,结果负时为1.
		ZF zero flag 零标志 运算结果等于0时为1,否则为0.
		CF carry flag 进位标志 最高有效位产生进位时为1,否则为0.
		AF auxiliary carry flag 辅助进位标志 运算时,第3位向第4位产生进位时为1,否则为0.
		PF parity flag 奇偶标志 运算结果操作数位为1的个数为偶数个时为1,否则为0.
		DF direcion flag 方向标志 用于串处理.DF=1时,每次操作后使SI和DI减小.DF=0时则增大.
		IF interrupt flag 中断标志 IF=1时,允许CPU响应可屏蔽中断,否则关闭中断.
		TF trap flag 陷阱标志 用于调试单步操作. 			
	*/

}
一、示例    
assume cs:cjcodesegment     
cjcodesegment segment   
mov ax,2    
add ax,ax   
add ax,ax   
mov ax,4c00H    
int 21H    
cjcodesegment ends      
end     
解析    
assume cs:cjcodesegment表示假设cs寄存器与cjcodesegment段有联系      
cjcodesegment segment表示cjcodesegment段开始   
mov ax,2    
add ax,ax   
add ax,ax   
cjcodesegment ends表示cjcodesegment段结束      
end表示 整个程序结束     
mov ax,4c00H    
int 21H     
这两条指令放在程序末尾让程序返回

二、mov与add
例一:
程序段中指令    指令执行后AX中数据  执令执行后BX中数据
mov ax,4E20H    4E20H               0000H
add ax,1406H    6226H               0000H
mov bx,2000H    6226H               2000H
add ax,bx       8226H               2000H
mov bx,ax       8226H               8226H
add ax,ax       044CH               8226H
注意:mov ax,[bx]表示ds:bx的内存值写入ax
例二:
已知(10000H)=23H,10001H=11H,10002H=22H,10003H=66H
mov ax 1000H    ax=1000H
mov ds,ax       ds=1000H
mov ax,[0]      ax=1121H
mov bx,[2]      bx=6622H
mov cx,[1]      cx=2211H
add bx,[1]      bx=8833H
add cx,[2]      cx=8833H
例三:
mov ax,123BH
mov ds,ax
mov ax,0
add ax,[0]
add ax,[2]
add ax,[4]
将数据段的前三个字加到ax

三、段地址
8086CPU可一次传16位即2个字节,win32反汇编时可以发现1次传4字节,注意物理地址=段地址*16+偏移地址,在十六进制表示时就是左移一位
mov bx,1000H//1000H就是16位,因为16进制下1个数字就是4位,两个数字就是一个字节,一次传1000H就是传两个字节
mov ds,bx
mov ax,[3]	//把(1000:3)10003H(低位)及10004H(高位)的数据读入ax
mov [3],cx	//把cx的数据读入(1000:3)10003H(低位)及10004H(高位)

四、栈地址
栈的地址是从1000FH到10000H,栈空时指向10010H,因为SP是16位,所以可以指向64K个字节范围,这个就是栈的量大范围
push ax
    sp=sp-2,即地址减小2字节(8086是16位)
    把ax写入ss:sp
pop ax
    把ss:sp写入ax
    sp=sp+2,即地址增加2字节(8086是16位)
例:
mov ax,1000H
mov ss,ax
mov sp,0010H
mov ax,001AH
mov bx,001BH
push ax
push bx
sub ax,ax   2B机器码,如果mov ax,0就是3个机器码
sub bx,bx   这里演示了AX与BX清0后用栈来恢复
pop bx      如果是先pop ax就是互换
pop ax

五、描述性符号
(x)就是取出x处的内容,例如:
(ax)=0010H          mov ax,0010H
(21000H)=0010H      mov [0],0010H(ds=2100H)
(ax)=((ds)*16+2)    mov ax,[2]
(ax)=(ax)+2         add ax,2
(ax)=(ax)+(bx)      add ax,bx
idata表示常量

六、loop
【先总结一下:转移指令:无条件jmp(改CS:IP),条件if,循环Loop,过程call/ret,中断】
(cx)=(cx)-1
判断cx非零就跳到标号,是0就往下执行
例:求2^12
assume cs:code
code segment
    mov ax,2
    mov cx,11
s:  add ax,ax
    loop s
    mov ax,4c00h
    int 21h
code ends
end

七、and
mov al,01100011B
and al,00111011B
此时al=00100011B

八、or
mov al,01100011B
and al,00111011B
此时al=01111011B

九、jmp
jmp short s表示s是一个8位的段内地址(直接操作数)
jmp near s表示s是一个16位的段内地址(直接操作数,可以理解为CS:IP计算出的具体值)
jmp far ptr s表示一个偏移位移即IP,是段间跳转(直接操作数,要预先赋好CS的值)
jmp word ptr s表示s明确给出CS:IP如ds:[0],或s是寄存器16位的值如[bx](内存或寄存器)
jmp dword ptr s表示s是ds:[0],从s处开始存两个字(4字节),后入栈的是目的段地址,先入栈的是目的偏移地址(内存或寄存器)
例一:
assume cs:codesg
codesg segment
    start:  mov ax,0
            jmp short s
            add ax,1    显然add这行代码没有被执行
    s:      inc ax
codesg ends
end start
注意:翻译成机器码时,上面的s会变成是相对于现在的地址而言偏移多少,所以机器中没有出现s
例二:
assume cs:codesg
codesg segment
start:  mov ax,0
        mov bx,0
        jmp far ptr s
        db 256 dup (0)
    s:  add ax,1
        inc ax
codesg ends
end sta
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值