A. 汇编程序:接受键盘输入字符,若输入为字母,则显示"L",若为数字,则显示"D",其他的则显示"O"。
直接写主程序哈:
START: MOV AH,1
INT 21H
CMP AL,30H
JB OTHER
CMP AL,39H
JA NEXT
NUM1: MOV DL,'D'
MOV AH,2
INT 21H
JMP EXIT
NEXT: CMP AL,41H
JB OTHER
CMP AL,'Z'
JB CHR
CMP AL,'a'
JB OTHER
CMP AL,'z'
JA OTHER
CHR: MOV DL,'L'
MOV AH,2
INT 21H
JMP EXIT
OTHER: MOV DL,'O'
MOV AH,2
INT 21H
EXIT: RET
B. c程序o文件怎样反汇编
在编程世界中,C语言和Pascal等高级语言被广泛用于开发软件。编写完成的代码经过编译器转化为可直接被计算机系统执行的执行文件。
然而,在某些情况下,我们可能需要将执行文件还原到更底层的语言,如汇编语言或其他高级语言。这个过程称为反汇编,其目的是将机器语言代码转换回原始的编程语言代码。尽管反汇编后的代码和原始代码的执行结果相同,但其结构和语法通常会有显着差异,非编程专家往往难以理解。
为了进行反汇编,程序员可以使用专门的工具和软件,如DEBUG等。这些工具提供了将二进制文件转换回汇编代码的功能。例如,通过在DEBUG中使用命令“-u”,可以实现文件位置的反汇编操作。尽管反汇编后的代码与原始代码存在差异,但通过这种方式,程序员可以进行逆向工程,修改代码,例如,对于Flash文件生成的SWF文件,也能够通过反汇编转化为Flash源代码。
C. O语言的简述
O语言是一款中文计算机语言(或称套装),各部分开发状态:
O汇编语言(简称OASM,√)
O中间语言(简称OML,√)
O高级语言(简称OXX,×)
界面描述语言(简称OFL,√)
窗口设计(√)
目前窗口设计、界面描述语言、O中间语言已经能很好的整合在一起(1.0.2.2版),基本有VB的事件驱动和窗口设计功能(但还不能创建COM控件,自带控件也很少)。 顾名思义O汇编语言也是一门汇编语言,它具有传统汇编语言的基本特点,也有与它们诸多不同之处。O汇编语言一个最大显着的特点是支持语言配置,使得它可以支持所有你想支持的语言,当然,O汇编语言的初衷是为了支持中文,所以它可以非常好的支持中文汇编。如果你已经习惯了其它英文的汇编模式,比如你喜欢用EAX、EBP类似这样的方式来命名寄存器,不要紧,只需要修改一下语言配置文件,这可以轻松做到。O汇编语言另一个显着的特点是指令使用非常直观和人性化,在不缺失汇编语言灵活性的情况下,使汇编语句的语意可以很直观地表现出来,这主要得益于用了一些象征性的符号,使得汇编语句不再是千篇一律的(指令 寄存器,内存操作数) 这样的格式,而是更像 (寄存器 操作符 内存操作数)这样的格式,不但容易理解,而且便于记忆,使汇编语言不再那么枯燥,使人一团雾水。
当然,在这里我还是着重介绍怎么用中文来编写程序,汇编语言通常是分段的,O汇编语言也是如此,下面是O汇编语言的基本格式:
.位模式 32 ∥指明是16位、32位还是64位的代码
文本编写方式 符号编写方式
∥这里包含一些头文件和库的引用
.包含文< 文件名 > 《 》
.引用库< 库文件 > 〈 〉
∥数据段
.数据段 ︻
{
} ︼
∥只读段
.只读段 ﹃
{
} ﹄
∥外部引用段
.引用段 ︽
{
} ︾
∥代码段开始
.代码段 ︷
{
∥开始函数定义
∏主函数()
{
∥这里添加代码
}
} ∥代码段结束 ︸
首先介绍注释方式,O汇编语言使用行注释与块注释方式,并分别支持两种符号编写方式。第一种支持C语言模式的注释方式,即:以”//”双左斜杠为行注释符,以”/* */”作为块注释符。第二种方式是以‘∥’这个符号作为行注释的开始,以”“ ””这两个符号作为块注释符。在一行中只要遇到行注释符,这行内以这个符号之后的文字都被忽略,在两个注释块符号之间的所有文字也都被忽略。
// 这行内这之后的文字被忽略
/*
这些文字被忽略
*/
∥ 这行内这之后的文字被忽略
“
这些文字被忽略
” O中间语言可以说是汇编语言的抽象,它和汇编语言一样,使用单句的语法,除了基本的条件句和函数调用外,基本的一条指令对应一条语句,因此,它比C语言在语法上更低级一些。这样设计的目的是为了保持底层足够大的灵活性,使前端代码比较容易地映射到中间语言。C语言毋庸置疑是很强大,Pascal语言也非常强大,但是你很难将两者代码进行相互转换,如果使用中间语言作为中间层,就能够兼容两者的语法。
O中间语言使用了挂载技术,使前端代码的解析与后端代码生成操作进行了分离,使用这一技术只须扩展相应的前端语法就能支持多种语法。所有挂载的接口都封装在OMount.dll的动态链接库中。
与O汇编语言相比之下的特色:
1.去除了汇编中段的概念(方便调用API,仍保留“引用段”)。
2.增加了控制台和动态链接库的创建。
3.增加数组支持。
4.增加for语句,格式:设(;;;){}
5.增加do...while语句,格式:执行{}当()
6.增进循环语句。
7.增加字符变量。
8.去除了汇编语言中的寄存器概念。
9.增进了语法,“如果”也可以写成“若”等。
10.支持英文语句,如“函数”可写为function,如果写为if,否则写为else,.包含文写为.include等等。
11.可以直接支持masm32的宏定义。
12.可以直接使用O汇编的函数,须在引用段进行调用,调用方式为API的调用方式。
13.增加了指针支持。
D. Gcc 和 Clang
GCC 编译器作为 linux 系统下的主要 C/C++ 编译工具,广泛安装于多数 Linux 发行版中。其命令形式通常为“gcc”,并提供了丰富的选项来辅助编译过程。其中,常用选项包括:-E 仅执行预处理,-c 编译或汇编源文件但不执行链接,-S 完成编译但不汇编,仅生成汇编代码,-o 用于指定输出文件名。在 Linux 系统中,未指定输出文件名时,默认输出名为“a.out”,源文件后缀生成为“.o”,汇编文件后缀为“.s”。GCC支持多种环境的代码生成,如使用-m32、-m64、-m16选项生成不同位数环境的代码,例如,-m32下int、long和指针类型均为32位,-m64下int为32位,long和指针类型为64位,-m16与-m32类似,但在汇编文件开头添加了gcc汇编制导,用于运行16位模式的二进制文件。
编译过程主要分为预处理、编译、汇编和链接四个阶段。下面以一段源码为例,详细分析每个阶段的内容。
首先,预处理过程会展开宏定义和条件编译,生成预处理文件。使用cpp命令执行预处理,得到的sample.i文件中,宏定义和条件编译已根据实际情况展开,宏引用被替换为实际值。通过-D指令可以自定义宏的值,进行预处理。在Linux系统下,通过“man gcc”可查询GCC命令的详细用法。
接着,GCC将预处理文件编译为汇编代码,生成汇编文件。汇编文件包含了核心的汇编代码,展示了编译过程中的汇编指令和数据操作。对比32位机器和64位机器汇编代码的差异,可以发现主要在于寄存器的位宽和指令的位宽不同。
汇编代码中,.cfi_startproc和.cfi_endproc用于初始化和结束本地数据结构,本地标签用于分支目的地标记。基本汇编指令如pushl、movl、subl、cmpl、je、addl、sall、ret、movl等,分别用于操作寄存器、存储数据、进行算术运算和逻辑运算、控制流程等。了解这些基本指令的用途有助于深入理解程序的执行流程。
使用GCC的-c选项编译源代码为机器代码,通过-o选项指定输出文件名。可以使用as命令得到机器语言,通过objmp指令查看目标文件的机器码,反汇编指令帮助理解机器码的含义。在程序中发现符号定义冲突时,可以使用nm命令列出目标文件中的符号,快速定位问题。
最后,链接器(ld)将编译生成的目标文件链接为可执行文件。链接过程中,链接器解析未定义的符号引用,将目标文件中的占位符替换为实际的符号地址。如果缺少必要的CRT文件,ld会生成警告。可通过查询/usr/lib/x86_64-linux-gnu路径找到CRT文件。C运行时文件(CRT)包含程序入口函数_start,负责调用__libc_start_main初始化libc,并调用main函数;_init函数在main函数前运行;_fini函数在main函数后运行。链接时使用-lc选项链接C标准库。
Clang 是一个基于LLVM的C/C++编译器,提供C/C++/Objective C/Objective C++语言的编译支持,旨在超越GCC。Clang预处理、生成汇编代码、生成目标文件、得到可执行文件的过程与GCC类似,但Clang提供了更多的特性,如更快的编译速度、更好的错误诊断和更先进的类型推断能力。使用Clang替代GCC进行C程序编译时,可以体验到这些额外的优势。
Clang编译过程包含预处理、生成32位和64位机器汇编代码、生成目标文件和得到可执行文件等步骤。使用Clang编译后的汇编代码、目标文件和可执行文件与GCC编译结果一致,但Clang在性能和语言支持方面可能具有优势。
E. 汇编指令test的用法
test属于逻辑运算指令,其功能为功能执行BIT与BIT之间的逻辑运算和测试功能(两操作数作与运算,仅修改标志位,不回送结果)。
Test对两个参数(目标,源)执行AND逻辑操作,并根据结果设置标志寄存器,结果本身不会保存。EST AX, BX与AND AX, BX命令有相同效果。TEST语法规格:TEST r/m,r/m/data。其影响标志包括:C,O,P,Z,S(其中C与O两个标志会被设为0)。
test的运用举例:利用Test指令测试一个位,例如寄存器:
test eax, 100b;/b后缀意为二进制/
jnz ******;/如果eax右数第三个位为1,jnz将会跳转/
jnz跳转的条件非0,即ZF=0,ZF=0意味着零标志没被置位,即逻辑与结果为1。
与汇编指令test功能相仿的还有cmp指令,CMP属于算术运算指令,其功能为功能为比较两个值(寄存器,内存,直接数值),与Test指令的测试功能相仿,其语法格式为CMP r/m,r/m/data,影响的标志位包括C,P,A,Z,O。
CMP比较.(两操作数作减法,仅修改标志位,不回送结果)。cmp实际上是只设置标志不保存结构的减法,并设置Z-flag(零标志)。零标志很像carry,也是内部标志寄存器的一位。