1.汇编语言如何去操作?
事实上,在实模式中,内存比保护模式中的结构更令人困惑。
内存被分割成段,并且,操作内存时,需要指定段和偏移量。不过,理解这些概念是非常容易的事情。
请看下面的图: 段-寄存器这种格局是早期硬件电路限制留下的一个伤疤。地址总线在当时有20-bit。
然而20-bit的地址不能放到16-bit的寄存器里,这意味着有4-bit必须放到别的地方。因此,为了访问所有的内存,必须使用两个16-bit寄存器。
这一设计上的折衷方案导致了今天的段-偏移量格局。最初的设计中,其中一个寄存器只有4-bit有效,然而为了简化程序,两个寄存器都是16-bit有效,并在执行时求出加权和来标识20-bit地址。
偏移量是16-bit的,因此,一个段是64KB。下面的图可以帮助你理解20-bit地址是如何形成的: 段-偏移量标识的地址通常记做 段:偏移量 的形式。
由于这样的结构,一个内存有多个对应的地址。例如,0000:0010和0001:0000指的是同一内存地址。
又如, 0000:1234 = 0123:0004 = 0120:0034 = 0100:0234 0001:1234 = 0124:0004 = 0120:0044 = 0100:0244 作为负面影响之一,在段上加1相当于在偏移量上加16,而不是一个“全新”的段。 反之,在偏移量上加16也和在段上加1等价。
某些时候,据此认为段的“粒度”是16字节。 练习题 尝试一下将下面的地址转化为20bit的地址: 2EA8:D678 26CF:8D5F 453A:CFAD 2933:31A6 5924:DCCF。
2.C嵌入汇编怎么表示汇编中的call00ff184?
在 Visual C++ 中使用内联汇编- - 使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤。
在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工具。 这里,我们就以 Visual Studio 。
NET 2003 为背景,介绍在 Visual C++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入)。 内联汇编代码可以使用 C/C++ 变量和函数,因此它能非常容易地整合到 C/C++ 代码中。
它能做一些对于单独使用 C/C++ 来说非常笨重或不可能完成的任务。 一、优点 使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤。
在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工具。 这里,我们就以 Visual Studio 。
NET 2003 为背景,介绍在 Visual C++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入)。 内联汇编代码可以使用 C/C++ 变量和函数,因此它能非常容易地整合到 C/C++ 代码中。
它能做一些对于单独使用 C/C++ 来说非常笨重或不可能完成的任务。 内联汇编的用途包括: 使用汇编语言编写特定的函数; 编写对速度要求非常较高的代码; 在设备驱动程序中直接访问硬件; 编写 naked 函数的初始化和结束代码。
二、关键字 使用内联汇编要用到 __asm 关键字,它可以出现在任何允许 C/C++ 语句出现的地方。我们来看一些例子: 简单的 __asm 块: __asm { MOV AL, 2 MOV DX, 0xD007 OUT AL, DX } 在每条汇编指令之前加 __asm 关键字: __asm MOV AL, 2 __asm MOV DX, 0xD007 __asm OUT AL, DX 因为 __asm 关键字是语句分隔符,所以可以把多条汇编指令放在同一行: __asm MOV AL, 2 __asm MOV DX, 0xD007 __asm OUT AL, DX 显然,第一种方法与 C/C++ 的风格很一致,并且把汇编代码和 C/C++ 代码清楚地分开,还避免了重复输入 __asm 关键字,因此推荐使用第一种方法。
不像在 C/C++ 中的"{ }",__asm 块的"{ }"不会影响 C/C++ 变量的作用范围。同时,__asm 块可以嵌套,而且嵌套也不会影响变量的作用范围。
为了与低版本的 Visual C++ 兼容,_asm 和 __asm 具有相同的意义。 另外,Visual C++ 支持标准 C++ 的 asm 关键字,但是它不会生成任何指令,它的作用仅限于使编译器不会出现编译错误。
要使用内联汇编,必须使用 __asm 而不是 asm 关键字。 三、汇编语言 1。
指令集 内联汇编支持 Intel Pentium 4 和 AMD Athlon 的所有指令。 更多其它处理器的指令可以通过 _EMIT 伪指令来创建(_EMIT 伪指令说明见下文)。
2。 MASM 表达式 在内联汇编代码中,可以使用所有的 MASM 表达式(MASM 表达式是指用来计算一个数值或一个地址的操作符和操作数的组合)。
3。 数据指示符和操作符 虽然 __asm 块中允许使用 C/C++ 的数据类型和对象,但它不能使用 MASM 指示符和操作符来定义数据对象。
这里特别指出,__asm 块中不允许 MASM 中的定义指示符(DB、DW、DD、DQ、DT 和 DF),也不允许使用 DUP 和 THIS 操作符。 MASM 中的结构和记录也不再有效,内联汇编不接受 STRUC、RECORD、WIDTH 或者 MASK。
4。 EVEN 和 ALIGN 指示符 尽管内联汇编不支持大多数 MASM 指示符,但它支持 EVEN 和 ALIGN。
当需要的时候,这些指示符在汇编代码里面加入 NOP 指令(空操作)使标号对齐到特定边界。 这样可以使某些处理器取指令时具有更高的效率。
5。 MASM 宏指示符 内联汇编不是宏汇编,不能使用 MASM 宏指示符(MACRO、REPT、IRC、IRP 和 ENDM)和宏操作符(、!、&、% 和 。
TYPE)。 6。
段 必须使用寄存器而不是名称来指明段(段名称"_TEXT"是无效的)。并且,段跨越必须显式地说明,如 ES:[EBX]。
7。 类型和变量大小 在内联汇编中,可以用 LENGTH、SIZE 和 TYPE 来获取 C/C++ 变量和类型的大大小。
* LENGTH 操作符用来取得 C/C++ 中数组的元素个数(如果不是一个数组,则结果为 1)。 * SIZE 操作符可以获取 C/C++ 变量的大小(一个变量的大小是 LENGTH 和 TYPE 的乘积)。
* TYPE 操作符可以返回 C/C++ 类型和变量的大小(如果变量是一个数组,它得到的是数组中单个元素的大小)。 例如,程序中定义了一个 8 维的整数型变量: int iArray[8]; 下面是 C 和汇编表达式中得到的 iArray 及其元素的相关值: __asm C Size LENGTH iArray sizeof(iArray)/sizeof(iArray[0]) 8 SIZE iArray sizeof(iArray) 32 TYPE iArray sizeof(iArray[0]) 4 8。
注释 内联汇编中可以使用汇编语言的注释,即";"。例如: __asm MOV EAX, OFFSET pbBuff ; Load address of pbBuff 因为 C/C++ 宏将会展开到一个逻辑行中,为了避免在宏中使用汇编语言注释带来的混乱,内联汇编也允许使用 C/C++ 风格的注释。
9。 _EMIT 伪指令 _EMIT 伪指令相当于 MASM 中的 DB,但是 _EMIT 一次只能在当前代码段(。
text 段)中定义一个字节。例如: __asm { JMP _CodeLabel _EMIT 0x00 ; 定义混合在代码段的数据 _EMIT 0x01 _CodeLabel: ; 这里是代码 _EMIT 0。
3.用汇编语言写一个扫雷程序,要求实现类似于windows下的扫雷游?
部分: dim a(10,10),b(100) as long For i = 1 To 10 For j = 1 To 10 a(i, j) = "0" Next j Next i For k = 1 To 20 '²¼À* 10: a1 = Int(Rnd * 10) + 1 b1 = Int(Rnd * 10) + 1 If a(a1, b1) = "0" Then a(a1, b1) = "*" n = n + 1 Else GoTo 10 End If Next k 'ÉèÖÃÀ*±ßÉϵÄÊý*Ö For n = 2 To 9 'ÖмäÅÐ¶Ï For t = 2 To 9 If a(n, t) = "*" Then For n1 = n - 1 To n + 1 For t1 = t - 1 To t + 1 If a(n1, t1) "*" Then a(n1, t1) = LTrim$(Str$(Val(a(n1, t1)) + 1)) End If Next t1 Next n1 End If Next t Next n For i = 2 To 9 If a(1, i) = "*" Then 'µÚÒ»ÐÐÅÐ¶Ï For j = 1 To 2 For k = i - 1 To i + 1 If a(j, k) "*" Then a(j, k) = LTrim$(Str$(Val(a(j, k)) + 1)) End If Next k Next j End If If a(10, i) = "*" Then 'µÚÊ®ÐÐÅÐ¶Ï For j = 9 To 10 For k = i - 1 To i + 1 If a(j, k) "*" Then a(j, k) = LTrim$(Str$(Val(a(j, k)) + 1)) End If Next k Next j End If Next i For i = 2 To 9 If a(i, 1) = "*" Then 'µÚÒ»ÐУ¬µÚiÁÐÅÐ¶Ï For j = i - 1 To i + 1 For k = 1 To 2 If a(j, k) "*" Then a(j, k) = LTrim$(Str$(Val(a(j, k)) + 1)) End If Next k Next j End If If a(i, 10) = "*" Then 'µÚiÐУ¬µÚÊ®ÁÐÅÐ¶Ï For j = i - 1 To i + 1 For k = 9 To 10 If a(j, k) "*" Then a(j, k) = LTrim$(Str$(Val(a(j, k)) + 1)) End If Next k Next j End If Next i 'Ëĸö½ÇÅÐ¶Ï If a(1, 1) = "*" Then 'µÚ1ÐУ¬µÚ1ÁÐÀ*ÅÐ¶Ï For i = 1 To 2 For j = 1 To 2 If a(i, j) "*" Then a(i, j) = LTrim$(Str$(Val(a(i, j)) + 1)) End If Next j Next i End If If a(1, 10) = "*" Then 'µÚ1ÐУ¬µÚ10ÁÐÀ*ÅÐ¶Ï For i = 1 To 2 For j = 9 To 10 If a(i, j) "*" Then a(i, j) = LTrim$(Str$(Val(a(i, j)) + 1)) End If Next j Next i End If If a(10, 1) = "*" Then 'µÚ10ÐУ¬µÚ1ÁÐÀ*ÅÐ¶Ï For i = 9 To 10 For j = 1 To 2 If a(i, j) "*" Then a(i, j) = LTrim$(Str$(Val(a(i, j)) + 1)) End If Next j Next i End If If a(10, 10) = "*" Then 'µÚ10ÐУ¬µÚ10ÁÐÀ*ÅÐ¶Ï For i = 9 To 10 For j = 9 To 10 If a(i, j) "*" Then a(i, j) = LTrim$(Str$(Val(a(i, j)) + 1)) End If Next j Next i End If For i = 1 To 100 b(i) = a((i - 1) \ 10 + 1, (i - 1) Mod 10 + 1) Next i 布雷为:10*10型 。
4.如何在 win10 64 位下完美配置搭建汇编环境
dos的话,用nasm而且要这样 nasm -f bin -o xxx.asm在里面开头写org 0200hbits 16然后后面就可以直接写汇编指令了和c互相调用的虽然其实gcc的内嵌汇编更好用一些,但是和vs搭配也是推荐nasm的,不过需要自己找vs 2015需要的配置文件,不太好找嗯nasm的语法比masm简洁好用很多嗯另外dosbox其实是一个16位模式的运行dos虚拟机,所以你用32位模式去编译,而且还是生成一个PE格式的,那自然是 cannot run in dos mode。
5.怎么用汇编语言编写A+B=C
; 本程序通过编译,运行正确
Code Segment
Assume CS:Code,DS:Code
A db 160
B db 248
Start: push cs
pop ds ;使数据段与代码段同段
mov al,A ;A→al
add al,B ;A+B→al
Exit_Proc: mov ah,4ch ;结束程序
int 21h
Code ENDS
END Start ;编译到此结束
转载请注明出处windows之家 » win10如何写汇编语言