汇编语言的寻址模式及示例

汇编语言——十种寻址方式 寻址方式 1.立即寻址方式 直接给寄存器赋值 MOV AH, 80H 2. 寄存器寻址方式 源或者目的有一个是寄存器 2.1) 源操作数是寄存器寻址方式 如:ADD VARD, EAX  ADD VARW, AX   MOV VARB, BH等。 其中:VARD、VARW和VARB是双字,字和字节类型的内存变量。 2.2) 目的操作数是寄存器寻址方式 如:ADD ... 阅读详情

1. 什么是汇编语言的寻址模式(或者编址模式)

        机器指令是计算机CPU可执行的指令,一条指令要包含操作符和操作的对象—操作数。对于Intel Processors指令集而言,有的指令没有操作数,有的有多个操作数(大于1个)。所谓寻址模式,就是我们写的代码要指明操作数在那里,这样CPU才能正确的找到操作数,执行这条指令。一条指令的操作数,可以直接包含在指令中,不需要去别的地方寻找;也可以是放在寄存器中,如果是放在寄存器中,直接取寄存器就行了;麻烦的就是操作数放在内存中,因为内存地址的形成相对复杂,你不能直接在内存的可访问地址范围内随便写一个地址,必须要按一定的规则形成内存地址,内存中的数据,有的是取这个内存的数据就可以,所谓直接方式,有的需要计算得出其存放地址,再通过地址取得内存中的数据,所谓间接方式。

2. 一些寻址的原则和容易混淆的地方

2.1 术语的翻译与称呼

opcode(operation code):操作码

operands:操作数

source:源操作数

destination:目标操作数

2.2 除了MOVS指令外,任何指令都不允许内存向内存传输数据。

2.3 有些操作数是显式指定的,有些则是隐含的。

2.4 源操作数的来源

(1) the instruction itself (an immediate operand)(来源于指令集本身,即包含在指令中,不用变量标号表示,就是直接数字,给他一个名称立即数。)。

(2) a register(来自某个寄存器)。

(3) a memory location(来自某个内存地址)。

(4) an I/O port(来自输入/输出端口)。

2.5 当指令返回数据给目的操作数时,可以返回数据到如下地方:

(1) a register(返给某个寄存器)。

(2) a memory location(返给某个内存地址)。

(3) an I/O port(返给输入/输出端口)。

2.6  这里所有指令以32位为示例。

3.  Operands(操作数)

3.1 Immediate Operands(立即操作数)

将数据编码在指令中作为源操作数,这样的源操作数称为立即操作数,简称立即方式,或称立即寻址。例如

MOV EAX,1234H

这时寄存器EAX显示为EAX = 00001234

这里区别于直接内存方式,这里不用变量代码常数,常数直接写在代码中,即源操作数不来自寄存器,不来自内存,也不来自I/O端口,不需要别的地方查找,编译后生成的可执行文件中这个常数就已经编码在文件中了,即立即就能用了。

3.2 Register Operands(寄存器操作数)

源操作数或者目的操作数可以是如下任何寄存器,取决于具体的指令:

(1)32-bit general-purpose registers (EAX, EBX, ECX, EDX, ESI, EDI, ESP, or EBP),即8个通用寄存器。

(2)segment registers (CS, DS, SS, ES, FS, and GS),即6个段寄存器。

(3) EFLAGS register(标识寄存器)。

(4) x87 FPU registers (ST0 through ST7, status word, control word, tag word, data operand pointer, and instruction poiter.(8个浮点寄存器),注意在很多国内作者编写的汇编语言教材中并没有讲浮点寄存器,也没有讲解浮点汇编指令,甚至提都没有提一笔。

(5) MMX registers (MM0 through MM7)(MultiMedia eXtensions):8个多媒体扩展寄存器。

(6) XMM registers (XMM0 through XMM7) and the MXCSR register: Streaming SIMD Extensions (SSE) is a single instruction, multiple data (SIMD) instruction set extension to the x86 architecture。(即SSE加入的8个128位寄存器XMM0到XMM7。)

(7) control registers (CR0, CR2, CR3, and CR4) and system table pointer registers (GDTR, LDTR, IDTR, and task register。(控制寄存器和系统表指针寄存器,以及任务寄存器)。

(8) debug registers (DR0, DR1, DR2, DR3, DR6, and DR7)。(调试寄存器)

(9) MSR registers(Model Specific Register)。(指的是在x86架构处理器中,一系列用于控制CPU运行、功能开关、调试、跟踪程序执行、监测CPU性能等方面的寄存器。)

3.3  Memory Operands(内存操作数)

在内存中的源操作数或者目的操作数是通过内存地址来访问的,其内存地址由segment selector(段选择子)和offset(偏移)构成。段选择子指定了包含操作数的内存段,偏移指定了这个操作数的线性地址或者有效地址。偏移可以是32位或16位。如下图所示:

什么又是段选择子,什么又是线性地址,什么又是有效地址呢?这在很多国产教材中都是一笔跳过,模糊不清,不知道是作者本身就不清楚还是觉得不重要,对于初学者来说极为恼火,这都没搞清楚后面的寻址模式怎么搞懂?

要搞清楚这些个问题,我们需要了解Intel IA32架构中对内存的组织,看看文档是上怎么来讲解的。

When employing the processor’s memory management facilities, programs do not directly address physical memory. Instead, they access memory using one of three memory models: flat, segmented, or real address mode:

(使用处理器的内存管理设施时,程序不能直接存取物理内存。而是使用以下三种内存模型中的一种存取内存:平坦型,分段型,或者实模式地址模型。下面分别介绍三种内存地址取存模型。

(1)  Real-address mode memory model(实地址模式内存存取模式):real mode(实模式)是专为8086和8088处理器而设计的,不是针对其它处理器设计的。是这两款处理器出现时特有的产物,它要解决在16位字长的机器里怎么提供20位地址的问题,而采用的办法是采用存储器地址分段的方法。实模式下允许处理器寻址的最大内存空间为:

       220 = 1048576 = 1024 K = 1M

因此实模式操作允许处理器寻址的内存空间仅仅为前面的1MB字节的内存空间,其它型号处理器不管是Pentium4还是Core2处理器,在实模式下也只能访问前面的1MB字节的空间。这1MB字节的内存空间就称为real memory(实内存),conventional memory(常规内存,相对护展内存而言),或者DOS memory system(DOS内存系统)。DOS系统是在实模式下运行的,而Windows系统不使用实模式,64位操作系统不能运行实模式下写的程序,要运行只能采取模拟的办法。

在实模式这里出现了内存的分段的概念(简称为段吧)。按照实模式的机制,需要把内存分成若干段,每个段内的地址空间是线性增长的,每个段的大小可以达64K,这样段内地址正好可以用16位表示:216 = 65535 = 64K。事实上,可以根据需要来确定段的任意大小,只要不超过64K。但是段不能起 始于任意地址,而必须从任意一小段的首地址开始。

下面就以64K为一个段来讲内存的划分。如下图

从图上看出,段的起始地址,即是每个分段在内存中的地址。同时,offset(偏移)和displacement(位移)的概念出现了,这两个概念常常让人混淆不清,究竟啥是偏移,啥是位移?

  • (segment)内存段:对内存按固定大小的分成的小段。在汇编译语言中经常提到的段寄存器,存放的就是这个分段在内存中的起始地址。如上图中,某一个段以10000H为段的开始地址,以1F000为段的结束地址,即下一个段的开始地址。这个时候,如果要对这一段内存进行某种操作,首先要把其首地址放入段寄存器。
  • Offset(偏移):偏移是相对于段的起始地址的字节数,如上图所示,某一段起始地址为10000H,有一个F000字节的内存段。但是这个F000字节的结束处的地址为:10000H+F000=1F0000H。即段的地址是相对于整个内存而言的,而移偏只是相对于当前段的起始地址而言的从0开始数的字节数,当计算其内存地址时要加上其段的首地址。那什么时候又出现一个displacement(位移)的概念呢?比如在以10000H为起始段的段的某两个位置存放了两个变量var1,var2,假设var2的地址更高,那么var2-var1的字节数就移为displacement(位移量),一点点微小区别。
  • 物理地址与逻辑地址:

什么是物理地址,什么又是逻辑地址呢?其实上面讲的都是逻辑地址,并不是实际的物理地址。8086的地址总线是20位的,能够表达的最大地址是220-1=0FFFFFH,所以它的直接寻址能力就是1M。只要给出一个20位的地址,就能从1MB内存中唯 一的读出一个字节来。位是CPU的寄存器和数据通路是设计成16位的,最大的存取单位和运算单位是16位的字,所以只能用字表示内存地址。那要怎样才能达到1MB的物理内存呢,可以有很多选择。一种方法是用“段基址:偏移”表示法。这在前面示例时的内存地址,就是这种表示法。

      用两个字节来表示一个内存地址,第一个叫段基础,第二个叫偏移,他们合起来就构成了一个逻辑地址,这是实模式下逻辑地址的定义,即其不是真正的物理地址,是程序中表示的地址。BIU在接到一个逻辑地址的时候,先把这个由两个字节构成的逻辑地址按照某种规则映射成20位的物理址,而后用这个物理地址选取内存中的指定单元。

这个映射规则是这样的:段基址向左移动4位(相当于乘以16),再加上偏移,得到20位的物理地址。

段基址x16+偏移=物理地址

因此,我们平时调试程序时见到的都只是逻辑地址。以上讲的是实模式下逻辑地址换算成物理地址的方法。

     在保护模式存储器寻址中,仍然要求程序员在程序中指定逻辑地址。而这个逻辑地址转换成物理地址的转换则相对比较复杂,保护模式下,逻辑地址由段选择子和偏移地址两部分来组成,选择子放在段寄存器中,但它不能直接表示段基地址,而是由操作系统通过一定的方法取得段基地址,再和偏移地址相加,从而求得所选单元的行理地址。这在保护模式时会讲到。

(2) Segmented memory model(段内存模式):看看手册上怎么说?

Memory appears to a program as a group of independent address spaces called segments. Code, data, and stacks are typically contained in separate segments. To address a byte in a segment, a program issues a logical address. This consists of a segment selector and an offset (logical addresses are often referred to as far pointers). The segment selector identifies the segment to be accessed and the offset identifies a byte in the address space of the segment. Programs running on an IA-32 processor can address up to 16,383 segments of different sizes and types, and each segment can be as large as 232 bytes. Internally, all the segments that are defined for a system are mapped into the processor’s linear address space. To access a memory location, the processor thus translates each logical address into a linear address. This translation is transparent to the application program. The primary reason for using segmented memory is to increase the reliability of programs and systems. For example, placing a program’s stack in a separate segment prevents the stack from growing into the code or data space and overwriting instructions or data, respectively.

内存在程序看来,就是一个一个单独的段,代码段,数据段,堆栈段就是典型的独立段。要访问一个段内存字节,程序关注的是逻辑地址,而不是其物理地址。处理器将每个逻辑地址转换成线性地址,这个转换对应用程序是透明的。分段的主要原因是对于编程和系统来说是可靠的,防止程序越界等。因此,这个内存模式工作在保护模式下,不能用于实模式工。

     其思想和实内存模式差不多。区别在于,取段的地址时,不是直接取段的首地址,而是引入了segment selector(段选择子)这个概念,段选择子由segment descriptor(段描述符)表达,段描述符记录了这个段的内存位置,长度,以及访问权限,放在一个descriptor table中。在个内存模型中,这个偏移又称为effective address(有效地址)。描述符的base address(基址部分)表示内存段的起始地址。

    段描述符又分为global descriptors(system descriptors),local descriptors(application descriptors)。

从出下图中看看其结构

(3) Flat memory model (平坦内存模式)

Memory appears to a program as a single, continuous address space. This space is called a linear address space. Code, data, and stacks are all contained in this address space. Linear address space is byte addressable, with addresses running contiguously from 0 to 232 - 1 (if not in 64-bit mode). An address for any byte in linear address space is called a linear address.

对程序来讲,其所见的地址空间是一个单一连续的线性地址空间,代码段,数据段,堆栈段都包括在这个线性地址空间中。线性地址空间是按字节编址的,其大小从0到232 – 1连续分布。

这三种内存模型的示意图如下

4.  专用寄存器

有些通用寄存器同时又有专用功能,一些专用寄存器就只有专用功能,说明如下:

  • EAX — Accumulator for operands and results data(通用寄存器,同时又作为操作的累加器和存放返回值)
  • EBX — Pointer to data in the DS segment(通用寄存器,同时又用于存放数据段寄存器指针)
  • ECX — Counter for string and loop operations(通用寄存器,同时又作为字符串和循环操作的计数器)
  • EDX — I/O pointer (通用寄存器,同时又作为输入/输出接口指针寄存器)
  • ESI — Pointer to data in the segment pointed to by the DS register; source pointer for string operations(通用寄存器,同时用于字符串操作数的源变址)
  • EDI — Pointer to data (or destination) in the segment pointed to by the ES register; destination pointer for string operations(通用寄存器,同时用于字符串操作数的目的变址)
  • ESP — Stack pointer (in the SS segment) 堆栈段指针
  • EBP — Pointer to data on the stack (in the SS segment) 数据堆栈指针

5. 寻址模式

5.1 Immediate Addressing(立即数寻址)

因为源操作数就在指令中,被编码成可执行代码跟在操作码后面。这里要注意区分的是,立即数是写在代码中的常数,目的操作数是寄存器。而从寄存器或者内存中传输数据是变量,不是立即数。

MOV EAX,1234H  ;这是立即数

MOV EAX,[1234H] ;这是引用内存地址,不是立即数

var  DWORD  1234H

MOV EAX,var   ;这是引用内存,不是立即数。

5.2 Direct Data Addressing(直接数据寻址)

直接数据寻址有两种形式,但两者共同点都是在段的逻辑地址(以后说的内存地址都是指逻辑地址,相对于物理地址而言)后面加一段位移(这里以段地址为起点,到某一个内存位置的距离,在这里也可以说是偏移)来形成地址:

(1) direct addressing(直接地址寻址)

也就是说直接用这个内存地址去取得这个数据。比如这样

var1  DWORD  1234H

MOV EAX,var1

也可以写成

MOV EAX,[var1]

如果var1这个变量标号的地址是00404024H

那我们也可以直接写这个地址

MOV EAX, [00404024H]

这样表示从理论上讲是可以的,但是实际上一般汇编器不支持这样表示。

为了和立即数区分,这里要加[]号,表示这是地址,汇编器会解析这个符号得到内存值。var1实际上是一个内存地址的符号表示,高级语言中定义的变量是同样的道理。

(2) displacement addressing(位移地址寻址)

段基址加一段位移形成地址,和直接地直寻基本没有什么区别。形如

MOV EAX,DS:[1234H]

唯一区别是,在生成机机器码的时候,direct addressing占用4个字节,而displacement addressing占用3个字节。

理论上来说,这样也是可以的

MOV [00404024H],EAX

但是一般汇编器不允许,如masm会报下面错误:

immediate operand not allowed

但加上段前缀就可以,这样

MOV DS:[00404024H],EAX

5.3  Register Addressing(寄存器寻址)

从源寄存器拷贝数据到目的寄存器。

MOV EAX,ECX

MOV EAX,1234H;立即寻址方式

MOV ECX,EAX;寄存器寻址

5.4  Register Indirect Addressing(寄存器间接寻址)

寄存器间接寻址可以访问可访问的任何内存地址的数据,其地址由存放在EBP,EBX,EDI和ESI四个寄存器中的偏移构成,其组合有多种形式。

当使用寄存器间接寻址,或者其它任何使用到寄存器EBX,EDI,或者ESI寄存器的寻址模式时,默认使用的是data segment(数据段)。

当使用EBP寄存器寻址内存的时候,默认使用的是stack segment(堆栈段)。特别注意,寄存器必须放在方括号里,两个寄存器可以放在一个方括号里,也可以分开放在两个方括号里,以表示形成址,偏移则可以放在方括号的前中后。

组合示例如下:

一个寄存器构成间接寻址:

MOV EAX,[EBX]

MOV EAX,[EBP]

MOV EAX,[ESI]

MOV EAX,[EDI]

使用一个寄存器和一个偏移间接寻址:

MOV EAX,[EBX+20];或者MOV EAX,20[EBX]

param DWORD 4

MOV EAX,[EBP+param]

MOV EAX,20[SI];或者MOV EAX,[ESI+20]

array DB 1,2,3,4,5

MOV EAX,array[EDI]

使用两个寄存器:

MOV EAX,[EBX+SI]; MOV EAX,[EBX][ESI];

MOV EAX,[EBP+ESI]; MOV EAX,[EBP][ESI]

MOV EAX,[EBX][EDI];或者MOV EAX,[EBX+EDI]

MOV EAX,[EBP][EDI];或者MOV EAX,[EBP+EDI]

使用两个寄存器加一个偏移

MOV EAX,[EBX+ESI+20]

MOV EAX,[EBP+ESI]param

MOV EAX,array[EBP][EDI]4

MOV EAX,20[EBX][EDI]

5.5 Base-Plus-Index Addressing(基址加变址寻址)

Index是可变的,所以称为变址寻址。为什么使用变址呢,因为前面的寻址方式,都是只是通过一个地址,一次访问到一个固定的内存单元,但是对数组这种情况,要访问数组的元索,这个内存地址取一个元素,地址就要变化一次,因此这种情况是变址。

基址加变址寻址和寄存器间接访问内存有点相似,对于访问数组来讲,基址寄存器通常存放的是这个数组的起始地址,变址寄存器则存放的数组元素的相对位置。

其实这里没有看到本质区别,单独把它列出来,只是为了分得更细一点,从名字称乎上可以与寻址模式对应起来,可以看到那个是基址,那个是变址,那个是偏移,那个又是相对位移。从名字上来说,这里只用到2个寄存器构成地址,即一个基址寄存器,一个变址寄存器。

其实指的是寄存器间接寻址中的使用两个寄存器构成偏移的情况,比如

MOV ECX,[EAX+EBX]

在这里,我们称EAX为(Base)基址,而EBX为Index(变址),如果这里用到了EBP寄存器,数据位于堆栈段,而不是数据段里。

对于一维数组的访问,可以使用这种方式。

​​​​​​​5.6 Register Relative Addressing(寄存器相对寻址)

可以归结为寄存器间接寻址的一种情况。和基址变址寻址相似,只是基址寻址的两个分量都是寄存器,即一个基址加一个变化地址的寄存器。而这里是在1个寄存器的基址上加了个偏移(或者称为位移也好),而不是变址寄存器,这里说的相对就是指这个相对于内存上某一个内存位置的偏移。

例如

MOV EAX,[EBX+20];这里20是相对偏移

即1个地寄存,再加1个偏移,构成基址+相对偏移的Register Relative Addressing(寄存器相对寻址)。

​​​​​​​​​​​​​​5.7 Base Relative-Plus-Index Addressing(基址相对寻址加变址寻址)

可以归结为寄存器间接寻址的一种情况。也就是将基址变址寻址与基址相对寻址结合,这样就用到2个寄存器,再加一个或多个偏移构成地址。

例如

MOV EAX,array[EBP][EDI]4;1个基址寄存器,1个变址寄存器,1个相对偏移array(相对于基段的基址),1个相对位移4(相对于数组的起始地址)。

​​​​​​​​​​​​​​5.8 Scaled-Index Addressing(按比例变址寻址)

这种寻址模式是80386到Core2的系列处理器专有的寻址模式。实现方式是一个寄存器作基地址,另一个寄存器乘以一个scaling factor(比例因子),两者构成操作数地址。这个比例因子的取值分别为:1,2,4,8。1的情况可以省略。

例如

MOV EAX,[EBX+2*ECX]

详细组合见图:

​​​​​​​​​​​​​​5.9 RIP Relative Addressing(RIP指针相对寻址)

这种寻址模式只用在64位环境下,内存模式为flat模型的环境下。

6. 段的选择

段的选择可以是显式的或者隐式的,处理器按照一套规则自动选择段是一个隐式的过程。通过指定segment selector(段选择子)来显示的指定那个段,例如:
MOV ES:[EBX], EAX

下表是Intel手册上列出的默认加载段的规则。

7. (POINTER DATA TYPES)指针数据类型

在非64位的模式下,架构定义了两种类型的指针,near pointer(近指针) 和 far pointer(远指针).近指针是一个段内的32位的偏移地址(也称为effective address(有效地址)),近指针在flat模式内存结构中可以访问所有可访问的内存,或者隐式的访问segment模式的内存。远指针是一个(logical address)逻辑地址,由一个16位的段选择子和1个32位(或16位)的偏移组成,远指针在段式模型的内存结构中必须显示的指定,否则不能访问其内存。其结构如下图:

汇编学习教程:寻址大总结 这里贴出一张寻址全家福:这张图里详细展示了目前我们已经学习过了所有灵活寻址方式,大家在后面的汇编开发中可以参考学习。 阅读详情

相关推荐

汇编语言寻址方式和寄存器分类

例: 假设指令:MOV AX, [BX+SI+200H],在执行时,(DS)=1000H,(BX)=2100H,(SI)=0010H,内存单元12310H的内容为1234H。例: 假设指令:MOV BX, [SI+100H],在执行它时,(DS)=1000H,(SI)=2345H,内存单元12445H的内容为2715H,问该指令执行后,BX的值是什么?由于数据段的段寄存器默认为DS,如果要指定访问其它段内的数据,可在指令中用段前缀的方式显式地书写出来。

m0_62946714的博客 5770

汇编语言的七种寻址方式

汇编语言的七种寻址方式 寻址方式即指令中指明的操作数存放位置的表达方式。 (一)操作数存放位置 指令中进行操作数的数据存放在三种位置:指令、寄存器、存储器 1.1 立即数——存放在指令中 被操作数据直接表示在指令的操作数字段,及操作码之后。 eg. MOV AL,10H 1.2寄存器操作数——存放在寄存器中 数据存放在CPU的寄存器中 eg. INC CX 1.3存储器操作数——存放在存储器中 存储器表示内存和I/O端口(段地址+偏移地址),数据的偏移地址在指令中表示。 eg. MOV AX, [2500H

计科陈同学 7175

计算机指令的构成要素及编程示例

不同的寻址模式适用于不同的场景,可以根据需要选择合适的寻址模式。操作码(Opcode):操作码是指令的核心部分,它指定要执行的操作类型。操作数用于指定指令要操作的数据或要操作的对象的地址。有些指令需要更多的操作码位数来表示更多的操作类型,扩展码提供了额外的位数来表示这些功能。指令由不同的组成部分组成,下面是对指令构成要素的详细解释,并附带一个简单的编程示例。需要注意的是,不同的计算机体系结构可能有不同的指令集和指令格式,上述示例是基于汇编语言的简化表示,实际的指令格式可能更加复杂。

SVIPCODE的博客 472

汇编7种寻址方式

8086/8088有7种基本的寻址方式:立即寻址,寄存器寻址,直接寻址,寄存器间接寻址,寄存器相对寻址,基址变址寻址,相对基址变址寻址。

dear_jing的博客 5935

9、深入浅出:汇编语言初探

本文深入浅出地介绍了汇编语言的基础知识,包括程序结构、语句类型、变量定义方法、常见寻址模式以及常用指令集。同时通过实例讲解了状态标志的使用,并探讨了汇编语言与C语言的混合编程方式,帮助读者更好地理解和应用底层开发技术。

sky77的博客 114

13、深入理解汇编语言中的寻址模式

本文深入探讨了汇编语言中的多种寻址模式,包括寄存器寻址、立即数寻址、直接寻址、间接寻址以及其他复杂寻址模式。通过具体示例详细解释了每种模式的使用方法,并分析了它们在不同应用场景下的优劣和优化策略。旨在帮助开发者更好地理解和运用这些模式,从而编写高效且可维护的汇编语言程序。

sky77的博客 109

006-汇编语言中的寻址模式

寻址模式是指令用来确定操作数位置的机制。它告诉处理器如何计算操作数的有效地址,从而找到指令需要的数据。不同的寻址模式提供了不同的方式来指定数据位置,使程序员能够灵活高效地访问寄存器、内存和立即数。

小宝哥Code的专栏 1920

25、核心汇编语言编程基础

本文深入介绍了汇编语言编程的核心基础,包括内存寻址模式、for循环的实现以及条件码的使用。通过具体的代码示例(如Ch11_05、Ch11_06和Ch11_07),详细展示了如何在x86-64架构下使用不同的内存寻址方式、编写高效的循环结构以及利用条件跳转和条件移动指令实现数值比较。此外,还讨论了实际应用中的优化建议和与高级语言结合的策略,帮助开发者更好地掌握底层编程技巧,提升程序性能。

o4p5q6r7s的博客 63

Intel 汇编语言

学习汇编语言是一个循序渐进的过程,从简单的指令开始,逐步学习寻址模式、栈、系统调用等高级特性。建议查找相关的教程和书籍,并尝试编写一些简单的程序来巩固你的学习成果。记住,这段代码需要使用合适的汇编器 (例如 NASM) 汇编,并链接到一个合适的启动文件才能运行在 Linux 系统上。虽然本文主要关注 Intel x86 架构,但需要注意的是,不同的处理器架构 (例如 ARM, MIPS) 拥有不同的指令集和汇编语法。寄存器指向的内存地址处的值。的值乘以 4 再加上 10 的结果所指向的内存地址处的值。

weixin_49342084的博客 1635

6、汇编语言中的比较、分支、循环与内存数据操作

本博客深入介绍了汇编语言中的比较、分支、循环以及内存数据操作的相关内容。文章详细讲解了比较指令如`cmpq`及其跳转指令的使用,同时探讨了条件码和相关条件指令如`cmov`系列和`loop`系列的工作机制。此外,还涉及了如何在程序中添加固定长度的数据段,并详细分析了多种内存寻址模式,包括立即数模式、寄存器模式、直接内存模式和寄存器间接寻址模式。通过多个代码示例和流程图,展示了这些指令和模式在实际编程中的应用,帮助读者更好地理解和掌握高效的汇编语言编程技巧。

python9snake的博客 183

神州数码OSPF实战配置详解(手把手教学)

本文提供神州数码设备上OSPF基础配置的详细实战教程。通过搭建典型的两台三层交换机互联实验环境,手把手演示了VLAN创建、接口IP配置、OSPF进程启动、Router-ID设置及网络宣告等核心步骤,并分享了邻居状态验证、路由检查及常见排错方法,帮助网络工程师快速掌握神州数码OSPF的配置要点与操作技巧。

weixin_29210727的博客 79

003-汇编语言基本语法

在.data段中定义初始化的数据:assembly;名称 定义方式 初始值单字节(8位)变量字(16位)变量双字(32位)变量四字(64位)变量单精度浮点数双精度浮点数;定义字符串", 0;C风格字符串(以0结尾);定义数组字节数组字数组;重复定义定义64字节的缓冲区,初始化为0在.bss段中定义未初始化的数据:assembly;名称 定义方式 大小保留64字节保留10个双字(40字节)保留4个四字(32字节)assembly.data单字节变量字变量。

小宝哥Code的专栏 1702

【转载】参数估计(Parameter Estimation):频率学派(最大似然估计MLE、最大后验估计MAP)与贝叶斯学派(贝叶斯估计BPE)

基础 频率学派与贝叶斯学派 http://www.douban.com/group/topic/16719644/ http://www.zhihu.com/question/20587681 最大似然估计(Maximum likelihood estimation,MLE) http://baike.baidu.com/view/1918804.htm http://baike.baidu.co

影 的专栏 3413

制作一个RISC-V的操作系统五-RISC-V汇编语言编程六(条件分支指令 伪指令 无条件跳转指令 问题 指令寻址模式总结)

B-type:B指代branch 6-11中:先是第11位然后才是1到4位 24-31中:先是5到10位,然后才是第12位符号扩展,所以是-20482和20472标号:标签类似地址 写loop不写地址值 汇编结果 无条件跳转指令 以寄存器值为基址来偏移跳转 AUPIC会构造一个32位的数,将IMM作为其高20位,并存放到X6中,然后JALR跳转到X6+IMM的低12位的值。所以整体来看就是跳转到X6+一个32位数值

llovewuzhengzi的博客 765

深入理解C语言内存管理:堆与栈的区别

栈是一种遵循后进先出(LIFO)原则的数据结构。在程序中,栈用于存储局部变量、函数的参数以及函数调用时的返回地址等信息。栈的内存管理由操作系统自动进行,每次函数调用时都会在栈上分配一块内存区域,函数执行完毕后,该内存区域会自动释放。在C语言中,堆与栈是两种不同的内存分配方式,各自有着不同的特点和适用场景。栈内存自动管理,访问速度快,但大小有限,适用于存储局部变量和函数调用信息。堆内存由程序员手动管理,适用于存储动态数据结构,大小不受限制,但访问速度较慢,容易导致内存泄漏等问题。

set_one的博客 1581

S4 Hana SD -信贷管理 - 03

自动信用控制将针对同一信用控制范围的不同的客户风险类别和信贷组执行不同的信用控制政策。对于ECC系统而言,无需单独设置检查规则,可在自动信贷控制进行设置即可,如图1-5-2。在S4 HANA版本中,自动信贷控制和检查规则是分离的。S4系统需要在定义自动信贷控制的时候,给字段“SAP信用管理”打钩,激活检查规则,然后需要单独在检查规则页签设置检查规则。接下来,我们分别介绍ECC和S4 HANA系统中两种不同配置方式.6.2SPRO。

weixin_46525734的博客 2888

计算机组成原理(一):计算机指令

计算机指令是计算机执行任务的基本单元,通过不同类型的指令和寻址模式,指令集提供了灵活的硬件控制能力。

www_dong的博客 2630

构网型逆变器下垂控制与电流限幅策略研究:理论、仿真与代码实现

随着分布式发电和微电网技术的快速发展,构网型(Grid-Forming, GFM)逆变器因其能够自主建立电压和频率参考、支撑弱电网及孤岛运行而受到广泛关注。本文提出并实现了一种基于下垂控制的构网型逆变器控制策略,将逆变器等效为受控电压源,通过L型滤波器接入配电网。在公共耦合点(PCC)处实时测量三相电压和电流,计算有功和无功功率,进而采用P-w和Q-V下垂控制生成内部频率和电压幅值,合成三相参考电压。针对故障情况下过电流问题,设计了一种自适应电流限幅模块:当电流幅值超过设定上限时,动态降低电压参考系数k_s

huanghm88的专栏 156

在手机上玩编程

在手机上玩编程 在手机上可以玩编程?对,可以,而且,玩的还是汇编,6502 汇编。那么,用什么软件呢?Jbit(http://sourceforge.net/projects/jbit/),一款开源的 J2ME 程序。6502汇编,还有人在用吗?有,文曲星系统在用,凌阳的cpu 也支持。 下面,简单介绍一下Jbit 的使用: 1、 启动程序后,出现如下界面 2、 选择 Demos 查看...

zwhc的专栏 568

LPDDR5 学习笔记02:上电初始化与下电时序

LPDDR5上电初始化流程需严格遵守时序要求:首先确保电源按顺序上电(VDD1→VDD2H→VDD2L→VDDQ),RESET_n保持低电平至电压稳定。初始化包含自动ZQ校准、命令总线训练(CBT)、WCK2CK电平校准和DQ总线训练四个关键阶段,需完成全部训练后才能正常操作。在双电源轨系统中,须在CBT前设置MR13寄存器。复位操作需保持RESET_n低电平至少tPW_RESET时间,断电时要求CS保持低电平且电源电压有序下降。非受控下电时电压斜率需低于0.5V/μs,器件生命周期内不得超过400次非受控

一只豌豆象的博客 2042

【批处理脚本】-0.1-如何运行批处理bat文件

如何运行批处理bat文件

「汽车电子助手」的博客 1585

汇编语言基本编程

1、指令 通用寄存器:AX(AH,AL),BX(BH,BL),CX(CH,CL),DX(DH,DL),SP,BP,SI,DI 段寄存器:DS、SS、ES、CS 直接寻址:[DISP] 寄存器间接寻址:[BX]、[BP]、[SI]、[DI] 基址寻址:[BX+DISP]、[BP+DISP] 变址寻址:[SI+DISP]、[DI+DISP] 基址加变址寻址:[BX+SI+DISP]、[B...

慧子 2559

BUG调试案例一:RK3588+YT8531网络无法PING通调试案例

在使用 RK3588 搭配 YT8531S PHY 芯片进行网络调试时,遇到了“网络无法 Ping 通”的棘手问题。排查了两天,终于找到问题原因。为了避免大家在类似项目中走弯路,也为了加深自己对调试细节的理解,我们特意整理了本次问题的完整排查过程。本篇文章将围绕以下四个方面展开分享: 问题现象&描述 调试过程&分析 问题根源定位 注意事项提醒 举一反三(走两步)

案例文章,高速信号 2336

ST7 汇编

       ST7汇编语言指令详细内容可参阅ST7 Programming User Manual,这里仅解释一些在编程过程中较容易被忽视的问题。 ST7 Core       ST7 MCU核有一个8位ALU,支持17种主要的寻址模式、63条指令;1个8位累加器(A);2个8位索引寄存器(X、Y);1个16位堆栈指针(SP);1个16位程序计数器(PC),1个状态寄存器(CC)。

Grant_jx的专栏 3288

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

GNU X86-64 汇编

源码 test.c #include <stdio.h> int main() { printf("hello world!"); return 0; } gcc -S test.c 生成test.s .file "test.c" .text .def __main; .scl 2; .type 32; .endef .section .rdat...

jadeshu的博客 954

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

汇编代码入门 AT&T指令格式

计算机系统结构 博文末尾支持二维码赞赏哦_ cpu内部:                1. PC Program Counter 指令指针寄存器 指向下一条指令的地址 EIP(X86-32)或者 RIP(X86-64) 2. 寄存器与寄存器堆   Registers 在处理器CPU内部以名字来访问的快速存储单元 3. 条件状态码    Condition C...

万有文的博客 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: Windows平台下Web缓存的一种实现方法
下一篇: 汇编语言标志寄存器
ComputerInBook
博客等级 码龄19年 1168粉丝 464原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值