一些汇编指令和寄存器。
2017-09-19 23:00
197 查看
今天学习C中对于一些代码中,执行原理不是清楚的了解,如简单的字符型char数据,编译器是如何处理的。以及等等很多只看过程远远不能清楚了解内部原理,对于学习有很深的障碍。所有有必要去学习基础汇编与寄存器的知识,通过编译器的反汇编来了解。
16位寄存器:
4个数据寄存器(AX,BX,CX,DX) 2个变址和指针寄存器(SI,DI)2个指针寄存器(SP,BP)
4个段寄存器(ES,CS,DS,SS) 1个指令指针寄存器(IP)1个标志寄存器(Flags)
32位寄存器:
4个数据寄存器(EAX,EBX,ECX,EDX) 2个变址和指针寄存器(ESI,EDI) 2个指针寄存器(ESP,EBP)
6个段寄存器(ES、CS、SS、DS、FS、GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)
一、数据寄存器:
AX通常称为累加器,用于乘、除运算、字的输出输入、中间结果的缓存。
BX通常称为基地址寄存器,用于作为存储器指针来使用。
CX通常计数寄存器,在循环和字符串操作时,要用它来控制循环次数,在位操作中,当移
多位时,要用CL来指明移位的位数。
DX通常称为数据寄存器,在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存
放I/O的端口地址。
在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据,保存算术逻辑运算结果,而且也可作为指针寄存器。
二、变址寄存器:
32位CPU的中两个寄存器ESI、EDI称为变址寄存器。它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
三、指针寄存器:
32位CPU中EBP、ESP称为指针寄存器。主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
注:
BP为基指针寄存器,用它可直接存取堆栈中的数据。
SP为堆栈指针寄存器,用它只可访问栈顶。
四、指令指针寄存器:
32位CPU中EIP为指令指针寄存器。指令指针EIP是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。
一些汇编指令:
mov指令
1、普通的mov指令
2、做符号扩展的movs
3、做零扩展的movz
类型:
普通的mov指令有 movb(完成一个字节的复制)movw(完成两个字节的复制)
movl(完成4个字节的复制)
movq(完成8个字节的复制)
movs指令: movsbw 作符号扩展的1字节复制到2字节
movsbl 作符号扩展的1字节复制到4字节
movsbq 作符号扩展的1字节复制到8字节
movswl 作符号扩展的2字节复制到4字节
movswq 作符号扩展的2字节复制到8字节
movslq 作符号扩展的4字节复制到8字节
movz指令:
movzbw
作0扩展的1字节复制到2字节
movzbl 作0扩展的1字节复制到4字节
movzbq
作0扩展的1字节复制到8字节
movzwl
作0扩展的2字节复制到4字节
movzwq 作0扩展的2字节复制到8字节
movzlq 作0扩展的4字节复制到8字节
为什么使用movs指令(符号扩展指令)
转:
如果要完成下面的c语言代
如果翻译成下面的汇编代码,会发现一个问题
用movb把%al寄存器里的-1,复制到%ebx寄存器,结果变成了255。等等,为什么会这样?
.section .text
.global _start
fmt:
.ascii "%d\n\0"
_start:
movb $-1, %al #把-1赋值到寄存器al
xorl %ebx, %ebx #把寄存器%ebx 赋值为0
movb %al, %bl #把al的值赋值到%ebx寄存器的低8位 (引用%ebx寄存器低8位的方法就是使用%bl寄存器)
xorq %rax, %rax
movl %ebx, %esi
movq $fmt, %rdi
call printf #调用printf 打印ebx寄存器的内容,会发现输出变成了255
movl $0, %edi #调用exit退出进程
call exit
接上段,学过原码,补码,反码的同学知道,在二进制的角度看待一个数。其在内存中表示正数,表示负数,依赖机器是怎么解释最高bit位的1。c语言里面signed类型,如果最高bit为1,认为它是一个负数。unsigned类型,始终认为是正数。
回到刚刚的-1变成255的问题。
作为用户,只想在由char 类型转为int,输出还是-1,就这么简单。
(事实上c语言已经做了自动转换,这里的char,int只是指代上面的汇编代码里的类型)
char类型的-1在内存中的表示:11111111
(由于最高bit位为1,且类型为signed,所以解释成-1)
使用movb指令把char类型的-1复制到int类型里:
char类型的-1复制到int类型在内存中的表示:00000000000000000000000011111111
(由于最高bit位为0,且类型为signed,所以解释成255)
int类型的-1在内存中的表示:11111111111111111111111111111111
两边一对比就知道,char复制到int需要把多出来的字节作符号位扩展
如果要完成下面的c语言代码:
unsigned char c = -1;
unsigned i = c;
printf("%x:%d\n", i, i); //输出 0xff, 255这时候就是movz指令大显身手的时候
movb $-1, %al #%al = 0xff
movzbl %al, %ebx #%ebx = 0x000000ff
使用:
1.CPU内部寄存器之间数的任意传送(除了码段寄存器CS和指令指针IP以外)。
2.立即数传送至CPU内部的通用寄存器组(即AX、BX、CX、DX、BP、SP、SI、DI)给这些寄存器赋初值。
3.CPU内部寄存器(除了CS和IP以外)与存储器(所有寻址方式)之间的数据传送,可以实现一个字节或一个字的传送。
4.能实现立即数给寄存器存储单元赋值。
eg:
MOV CL,4 ;CL←4,字节传送
MOV DX,0FFH ;DX←00FFH,字传送
MOV SI,200H ;SI←0200H,字传送
MOV BVAR,0AH ;字节传送
假设BVAR是一个字节变量,定义如下:BVAR DB 0
MOV WVAR,0BH ;字传送
假设wvar是一个字变量,定义如下:wvar dw 0
寄存器传送
mov ah,al ;ah←al,字节传送
mov bvar,ch ;bvar←ch ,字节传送
mov ax,bx ;ax←bx,字传送
mov ds,ax ;ds←ax,字传送
mov [bx],al ;[bx]←al,字节传送
存储器传送
mov al,[bx] ;al←ds:[bx]
mov dx,[bp] ;dx←ss:[bp+0]
mov dx,[bp+4] ;dx←ss:[bp+4]
mov es,[si] ;es←ds:[si]
段寄存器传送
MOV [SI],DS
MOV AX,DS ;AX←DS
MOV ES,AX ;ES←AX←DS
注:
1.MOV指令不能在两个寄存器之间进行数据直接传送。
2.MOV指令不能在两个段寄存器之间进行数据直接传送。
3.立即数不能直接传送给寄存器。
非法指令的主要现象:
两个操作数的类型不一致
无法确定是字节量还是字量操作
两个操作数都是存储器
段寄存器的操作有一些限制
① 目的操作数不能是立即寻址方式。
② 源操作数与目的操作数不能同时为存储器寻址方式,即两个内存单元之间不能直接传送数据。
③ 立即数不能直接送段寄存器,即段寄存器只能通过寄存器或存储单元传送数据。
④ 两个段寄存器之间不允许直接传送数据。
⑤ 不允许给CS、IP、PSW三个寄存器传送数据,即这3个寄存器的值用户无权改变。
⑥ 源操作数和目的操作数必须字长相等。
⑦ MOV指令不影响标志位。
交换指令
通用寄存器与通用寄存器之间交换
通用寄存器与累加器之间交换
通用寄存器或存储器之间交换
不能在两存储单元之间交换,段寄存器与指令指针IP也不能作为一个源或目标操作数。
lea指令
取[寄存器]的值
mov eax,4;
lea ebx,[eax];//执行后ebx=2
对于寄存器来说:第二个操作数是寄存器必须要加[],不然报错,这里lea就是取[寄存器]的值,如: mov eax,2
lea ebx,[eax];执行后ebx=2
mov ebx,eax;等同于上句
lea ebx,eax;编译器报错: error A2070: invalid instruction operands
对于变量来说加不加[]都是一样的效果,都是取变量的地址,相当于指针 如:
num dword 2;
lea ebx,num ;
lea eax,[num]; eax为num的地址,如eax=4206598,随程序不同不同,这时ebx==eax
mov中对于变量来说
num dword 2;
mov eax,2;
mov ebx,num;
mov ecx,[num];执行完ebx==ecx==2
mov中对寄存器
mov ebx,eax;ebx==2
mov ecx,[eax];可能会报错,因为这里翻译成汇编是mov ecx,DS:[eax]
lea对变量来说(无影响)取地址,对寄存器来说加[]时取值,不加[]时非法。
mov对变量来说(无影响)取值,对寄存器来说加[]取地址,不加[]是取值。
push指令
进栈指令 PUSH (push onto the stack)
出栈指令 POP (pop from the stack)
指令的汇编格式:PUSH SRC ;POP DST
指令的基本功能:PUSH指令在程序中常用来暂存某些数据,而POP指令又可将这些数据恢复。
PUSH SRC (SP)<-(SP)-2 ; (SP)<-(SRC)
POP DST (DST)<-((SP)); (SP)<-(SP)
指令支持的寻址方式:push 和 pop指令不能不能使用立即数寻址方式。
转:
进栈指令push
push reg/mem/seg;sp<-sp-2,ss<-reg/mem/seg
进栈指令先使堆栈指令sp减2,然后把一个字操作数存入堆栈顶部。堆栈操作的对象只能是字操作数,进栈时底字节存放于低地址,高字节存放于高地址,sp相应向低地址移动两个字节单元。
push AX
PUSH [2000H]
PUSH CS
出栈指令pop
pop reg/seg/mem;reg/seg/mem<-ss:[sp],sp<-sp+2
出栈指令把栈顶的一个字传送至指定的目的操作数,然后堆栈指针sp加2。目的操作数应为字操作数,字从栈顶弹出时,低地址字节送低字节,高地址字节送高字节。
pop AX
POP [2000H]
POP SS堆栈可以用来临时存放数据,以便随时恢复它们。也常用于子程序见传递参数。
注意几点:
(1)、因为堆栈指针sp总是指向已经存入数据的栈顶(不是空单元),所以PUSH指令是将(SP)减2,后将内容压栈(即先修改SP是指指向空单元,后压入数据),而POP是先从栈顶弹出一个字,后将堆栈指针SP加2.
(2)、PUSH CS是合法的,但是POP CS是不合法的。
(3)、因为SP总是指向栈顶,而用PUSH和POP指令存取数时都是在栈顶进行的,所以堆栈是先进后出或叫后进先出的。栈底在高地址,堆栈是从高地址向低地址延伸的,所有栈底就是最初的栈顶。
(4)、用PUSH指令和POP指令时只能按字访问堆栈,不能按字节访问堆栈。
(5)、PUSH和POP指令都不影响标志。
call指令与ret指令
call与ret都是转移指令,它们可以改变IP值,或者同时改变CS与IP的值,往往在程序中使用它们进行子程序模块的设计。
转:
ret用栈的数据修改IP的内容,实现近转移
retf用栈中的数据修改CS与IP的内容,实现远转移
ret执行步骤:
(1):(IP)=((SS)*16+SP)
(2):(SP)=(SP)+2
retf执行步骤:
(1):(IP)=((SS)*16+SP)
(2):(SP)=(SP)+2
(3):(CS)=((SS)*16+SP)
(4):(SP)=(SP)+2
可以将ret理解为:POP IP
可以将retf理解为:POP IP POP CS
CALL指令的执行步骤(call不能实现短转移):
(1)将当前的IP或CS与IP压入栈中
(2)转移
call 标号(将当前IP压栈,转移到标号处执行)
执行步骤:
(1) (sp)=(sp)-2
((ss)*16+(sp))=(ip) (实现当前IP值压栈)
(2)(ip)=(ip)+16位位移 (转移到标号处)
16位位移=标号处地址-call指令后的第一个字节的地址
位移范围为-32768-32767由补码给出
位移在编译时计算
call 标号 相当于 call near ptr 标号
16位寄存器:
4个数据寄存器(AX,BX,CX,DX) 2个变址和指针寄存器(SI,DI)2个指针寄存器(SP,BP)
4个段寄存器(ES,CS,DS,SS) 1个指令指针寄存器(IP)1个标志寄存器(Flags)
32位寄存器:
4个数据寄存器(EAX,EBX,ECX,EDX) 2个变址和指针寄存器(ESI,EDI) 2个指针寄存器(ESP,EBP)
6个段寄存器(ES、CS、SS、DS、FS、GS) 1个指令指针寄存器(EIP) 1个标志寄存器(EFlags)
一、数据寄存器:
AX通常称为累加器,用于乘、除运算、字的输出输入、中间结果的缓存。
BX通常称为基地址寄存器,用于作为存储器指针来使用。
CX通常计数寄存器,在循环和字符串操作时,要用它来控制循环次数,在位操作中,当移
多位时,要用CL来指明移位的位数。
DX通常称为数据寄存器,在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存
放I/O的端口地址。
在16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据,保存算术逻辑运算结果,而且也可作为指针寄存器。
二、变址寄存器:
32位CPU的中两个寄存器ESI、EDI称为变址寄存器。它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
三、指针寄存器:
32位CPU中EBP、ESP称为指针寄存器。主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
注:
BP为基指针寄存器,用它可直接存取堆栈中的数据。
SP为堆栈指针寄存器,用它只可访问栈顶。
四、指令指针寄存器:
32位CPU中EIP为指令指针寄存器。指令指针EIP是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。
一些汇编指令:
mov指令
1、普通的mov指令
2、做符号扩展的movs
3、做零扩展的movz
类型:
普通的mov指令有 movb(完成一个字节的复制)movw(完成两个字节的复制)
movl(完成4个字节的复制)
movq(完成8个字节的复制)
movs指令: movsbw 作符号扩展的1字节复制到2字节
movsbl 作符号扩展的1字节复制到4字节
movsbq 作符号扩展的1字节复制到8字节
movswl 作符号扩展的2字节复制到4字节
movswq 作符号扩展的2字节复制到8字节
movslq 作符号扩展的4字节复制到8字节
movz指令:
movzbw
作0扩展的1字节复制到2字节
movzbl 作0扩展的1字节复制到4字节
movzbq
作0扩展的1字节复制到8字节
movzwl
作0扩展的2字节复制到4字节
movzwq 作0扩展的2字节复制到8字节
movzlq 作0扩展的4字节复制到8字节
为什么使用movs指令(符号扩展指令)
转:
如果要完成下面的c语言代
char c = -1; int i = c;
如果翻译成下面的汇编代码,会发现一个问题
用movb把%al寄存器里的-1,复制到%ebx寄存器,结果变成了255。等等,为什么会这样?
.section .text
.global _start
fmt:
.ascii "%d\n\0"
_start:
movb $-1, %al #把-1赋值到寄存器al
xorl %ebx, %ebx #把寄存器%ebx 赋值为0
movb %al, %bl #把al的值赋值到%ebx寄存器的低8位 (引用%ebx寄存器低8位的方法就是使用%bl寄存器)
xorq %rax, %rax
movl %ebx, %esi
movq $fmt, %rdi
call printf #调用printf 打印ebx寄存器的内容,会发现输出变成了255
movl $0, %edi #调用exit退出进程
call exit
接上段,学过原码,补码,反码的同学知道,在二进制的角度看待一个数。其在内存中表示正数,表示负数,依赖机器是怎么解释最高bit位的1。c语言里面signed类型,如果最高bit为1,认为它是一个负数。unsigned类型,始终认为是正数。
回到刚刚的-1变成255的问题。
作为用户,只想在由char 类型转为int,输出还是-1,就这么简单。
(事实上c语言已经做了自动转换,这里的char,int只是指代上面的汇编代码里的类型)
char类型的-1在内存中的表示:11111111
(由于最高bit位为1,且类型为signed,所以解释成-1)
使用movb指令把char类型的-1复制到int类型里:
char类型的-1复制到int类型在内存中的表示:00000000000000000000000011111111
(由于最高bit位为0,且类型为signed,所以解释成255)
int类型的-1在内存中的表示:11111111111111111111111111111111
两边一对比就知道,char复制到int需要把多出来的字节作符号位扩展
如果要完成下面的c语言代码:
unsigned char c = -1;
unsigned i = c;
printf("%x:%d\n", i, i); //输出 0xff, 255这时候就是movz指令大显身手的时候
movb $-1, %al #%al = 0xff
movzbl %al, %ebx #%ebx = 0x000000ff
使用:
1.CPU内部寄存器之间数的任意传送(除了码段寄存器CS和指令指针IP以外)。
2.立即数传送至CPU内部的通用寄存器组(即AX、BX、CX、DX、BP、SP、SI、DI)给这些寄存器赋初值。
3.CPU内部寄存器(除了CS和IP以外)与存储器(所有寻址方式)之间的数据传送,可以实现一个字节或一个字的传送。
4.能实现立即数给寄存器存储单元赋值。
eg:
MOV CL,4 ;CL←4,字节传送
MOV DX,0FFH ;DX←00FFH,字传送
MOV SI,200H ;SI←0200H,字传送
MOV BVAR,0AH ;字节传送
假设BVAR是一个字节变量,定义如下:BVAR DB 0
MOV WVAR,0BH ;字传送
假设wvar是一个字变量,定义如下:wvar dw 0
寄存器传送
mov ah,al ;ah←al,字节传送
mov bvar,ch ;bvar←ch ,字节传送
mov ax,bx ;ax←bx,字传送
mov ds,ax ;ds←ax,字传送
mov [bx],al ;[bx]←al,字节传送
存储器传送
mov al,[bx] ;al←ds:[bx]
mov dx,[bp] ;dx←ss:[bp+0]
mov dx,[bp+4] ;dx←ss:[bp+4]
mov es,[si] ;es←ds:[si]
段寄存器传送
MOV [SI],DS
MOV AX,DS ;AX←DS
MOV ES,AX ;ES←AX←DS
注:
1.MOV指令不能在两个寄存器之间进行数据直接传送。
2.MOV指令不能在两个段寄存器之间进行数据直接传送。
3.立即数不能直接传送给寄存器。
非法指令的主要现象:
两个操作数的类型不一致
无法确定是字节量还是字量操作
两个操作数都是存储器
段寄存器的操作有一些限制
① 目的操作数不能是立即寻址方式。
② 源操作数与目的操作数不能同时为存储器寻址方式,即两个内存单元之间不能直接传送数据。
③ 立即数不能直接送段寄存器,即段寄存器只能通过寄存器或存储单元传送数据。
④ 两个段寄存器之间不允许直接传送数据。
⑤ 不允许给CS、IP、PSW三个寄存器传送数据,即这3个寄存器的值用户无权改变。
⑥ 源操作数和目的操作数必须字长相等。
⑦ MOV指令不影响标志位。
交换指令
通用寄存器与通用寄存器之间交换
通用寄存器与累加器之间交换
通用寄存器或存储器之间交换
不能在两存储单元之间交换,段寄存器与指令指针IP也不能作为一个源或目标操作数。
lea指令
取[寄存器]的值
mov eax,4;
lea ebx,[eax];//执行后ebx=2
对于寄存器来说:第二个操作数是寄存器必须要加[],不然报错,这里lea就是取[寄存器]的值,如: mov eax,2
lea ebx,[eax];执行后ebx=2
mov ebx,eax;等同于上句
lea ebx,eax;编译器报错: error A2070: invalid instruction operands
对于变量来说加不加[]都是一样的效果,都是取变量的地址,相当于指针 如:
num dword 2;
lea ebx,num ;
lea eax,[num]; eax为num的地址,如eax=4206598,随程序不同不同,这时ebx==eax
mov中对于变量来说
num dword 2;
mov eax,2;
mov ebx,num;
mov ecx,[num];执行完ebx==ecx==2
mov中对寄存器
mov ebx,eax;ebx==2
mov ecx,[eax];可能会报错,因为这里翻译成汇编是mov ecx,DS:[eax]
lea对变量来说(无影响)取地址,对寄存器来说加[]时取值,不加[]时非法。
mov对变量来说(无影响)取值,对寄存器来说加[]取地址,不加[]是取值。
push指令
进栈指令 PUSH (push onto the stack)
出栈指令 POP (pop from the stack)
指令的汇编格式:PUSH SRC ;POP DST
指令的基本功能:PUSH指令在程序中常用来暂存某些数据,而POP指令又可将这些数据恢复。
PUSH SRC (SP)<-(SP)-2 ; (SP)<-(SRC)
POP DST (DST)<-((SP)); (SP)<-(SP)
指令支持的寻址方式:push 和 pop指令不能不能使用立即数寻址方式。
转:
进栈指令push
push reg/mem/seg;sp<-sp-2,ss<-reg/mem/seg
进栈指令先使堆栈指令sp减2,然后把一个字操作数存入堆栈顶部。堆栈操作的对象只能是字操作数,进栈时底字节存放于低地址,高字节存放于高地址,sp相应向低地址移动两个字节单元。
push AX
PUSH [2000H]
PUSH CS
出栈指令pop
pop reg/seg/mem;reg/seg/mem<-ss:[sp],sp<-sp+2
出栈指令把栈顶的一个字传送至指定的目的操作数,然后堆栈指针sp加2。目的操作数应为字操作数,字从栈顶弹出时,低地址字节送低字节,高地址字节送高字节。
pop AX
POP [2000H]
POP SS堆栈可以用来临时存放数据,以便随时恢复它们。也常用于子程序见传递参数。
注意几点:
(1)、因为堆栈指针sp总是指向已经存入数据的栈顶(不是空单元),所以PUSH指令是将(SP)减2,后将内容压栈(即先修改SP是指指向空单元,后压入数据),而POP是先从栈顶弹出一个字,后将堆栈指针SP加2.
(2)、PUSH CS是合法的,但是POP CS是不合法的。
(3)、因为SP总是指向栈顶,而用PUSH和POP指令存取数时都是在栈顶进行的,所以堆栈是先进后出或叫后进先出的。栈底在高地址,堆栈是从高地址向低地址延伸的,所有栈底就是最初的栈顶。
(4)、用PUSH指令和POP指令时只能按字访问堆栈,不能按字节访问堆栈。
(5)、PUSH和POP指令都不影响标志。
call指令与ret指令
call与ret都是转移指令,它们可以改变IP值,或者同时改变CS与IP的值,往往在程序中使用它们进行子程序模块的设计。
转:
ret用栈的数据修改IP的内容,实现近转移
retf用栈中的数据修改CS与IP的内容,实现远转移
ret执行步骤:
(1):(IP)=((SS)*16+SP)
(2):(SP)=(SP)+2
retf执行步骤:
(1):(IP)=((SS)*16+SP)
(2):(SP)=(SP)+2
(3):(CS)=((SS)*16+SP)
(4):(SP)=(SP)+2
可以将ret理解为:POP IP
可以将retf理解为:POP IP POP CS
CALL指令的执行步骤(call不能实现短转移):
(1)将当前的IP或CS与IP压入栈中
(2)转移
call 标号(将当前IP压栈,转移到标号处执行)
执行步骤:
(1) (sp)=(sp)-2
((ss)*16+(sp))=(ip) (实现当前IP值压栈)
(2)(ip)=(ip)+16位位移 (转移到标号处)
16位位移=标号处地址-call指令后的第一个字节的地址
位移范围为-32768-32767由补码给出
位移在编译时计算
call 标号 相当于 call near ptr 标号
相关文章推荐
- 32位CPU寄存器和汇编指令
- 对寄存器ESP和EBP的一些理解
- (转)32位汇编指令 寄存器
- 对寄存器ESP和EBP的一些理解
- ASM X86&&X64 Registers 对寄存器ESP和EBP的一些理解
- 对寄存器ESP和EBP的一些理解
- 可以不接异步reset的一些寄存器
- 有关TI DSP的一些东西(整理一些网络资源及手册资料)--外设寄存器和CPU控制寄存器、数据类型、中断的使用
- 一些汇编指令
- 32位CPU寄存器和汇编指令
- 关于寄存器ESP和EBP的一些理解
- 寄存器和常用汇编指令
- 32位汇编寄存器及汇编指令
- 一些汇编指令
- ARM汇编指令的一些总结
- 对寄存器ESP和EBP的一些理解
- 寄存器和常用汇编指令
- C语言自定义寄存器操作的一些方法
- 关于寄存器ESP和EBP的一些理解
- 一些汇编指令