汇编

给初学者一封信

六眼飞鱼酱① 提交于 2020-11-27 04:44:59
我始终认为,对一个初学者来说,IT界的技术风潮是不可以追赶的,而且也没有能力去追赶。我时常看见自己的DDMM们把课本扔了,去卖些价格不菲的诸如C#, VB.Net 这样的大部头,这让我感到非常痛心。而许多搞不清指针是咋回事的BBS站友眉飞色舞的讨论C#里面可以不用指针等等则让我觉得好笑。C#就象当年的ASP一样,“忽如一夜春风来,千树万树梨花开”,结果许多学校的信息学院成了“Web 学院”。不少大学生都去做Web 了。当然我没有任何歧视某一行业的意识。我只是觉得如果他们把追赶这些时髦技术的时间多花一点在基础的课程上应该是可以走得更远的。 几个误区   初学者对C#风潮的追赶其实也只是学习过程中经常遇到的几个误区之一。我将用一些实际的例子来说明这些现象,你可以按部就班的看看自己是不是属于其中的一种或者几种: 认为计算机技术等于编程技术: 有些人即使没有这个想法,在潜意识中也有这样的冲动。让我奇怪的是,许多信息学院的学生也有这样的念头。认为计算机专业就是编程专业,与编程无关的,或者不太相关的课程他统统都不管,极端的学生只要书上没带“编程”两个字他就不看。 其实编程只是计算机技术应用过程中一种复杂性最低的劳动,这就是为什么IT业最底层的人是程序员(CODER)。计算机技术包括了多媒体,计算机网络,人工智能,模式识别,管理信息系统等等这些方面

8086汇编中的标识寄存器详解

时间秒杀一切 提交于 2020-04-09 20:02:40
每天都在学习。写点笔记。remark。 8086汇编中的标识寄存器叫flag。16位每一位都标识不一样的含义, 15 14 13 12 11( OF ) 10( DF ) 9( IF ) 8( TF ) 7( SF ) 6( ZF ) 5 4( AF ) 3 2( PF ) 1 0( CF ) 以上flag寄存器中各个位数表示的情况。在8086cpu中只用到了0,2,4,6,7,8,9,10,11这9个位数,其他的位数没有任何意义。 CF Carry Flag ,进位标志位 在进行 无符号 运算的情况下,它记录了运算结果的最高位有效位像更高位的进位值,或从更高位的借位值 CY(carry yes 进位) NC(No carry 未进位) PF Parity Flag 奇偶标志位 相关指令执行后,其结果所在bit位中1的个数是奇数或偶数,如果1个个数为偶数,则pf=1,为基数则pf=0 PE(parity even 偶) PO(parity odd 奇数) AF Auxiliary Flag 辅助进位 AC(assistant carry进位) NA(no assistant carry 无进位) ZF Zero Flag 零标志位 相关指令执行后,其结果是否为零,如果结果为零则zf=1 如果结果不为零则zf=0 ZF(zero等于零) NZ(no zero不等于零) SF Sign

C语言函数和汇编函数相互调用(转)

时光怂恿深爱的人放手 提交于 2020-03-25 08:34:27
3 月,跳不动了?>>> 在C程序main函数中,接收用户输入任意个整数,然后在main中调用使用ARM汇编编写的函数(在该函数中完成对这些整数的排序功能),然后再在C程序main函数中输出这些排好顺序的整数。 //main.c #include <stdio.h> int main() { int i=0; int num=0; int *array=NULL; while(num <= 0) //输入数组中元素的个数 { printf("please enter the number of elements:\n"); scanf("%d",&num); if(num > 0) {break;} } if(NULL == (array = (int *)malloc(num*sizeof(int)))) { printf("malloc failed!\n"); exit(-1); } printf("please enter the elements:\n"); for(i = 0; i<num; i++) { printf("\n%d:\t", i); scanf("%d", array+i); } sort(array, num);//调用相应的汇编的函数,注意分析传参过程 printf("The Result is:\n"); for(i = 0; i<num; i++

Golang 调用汇编代码,太方便啦

拥有回忆 提交于 2020-03-02 17:14:45
今天在翻阅Golang代码时,发现了Golang调用汇编代码的方法(详见pkg/bytes)。大概要做三件事,我以用汇编实现一个判断字符串是否相等的方法Equal为例,测试一下: 准备工作,创建工程目录: asm_demo |--bin |--pkg |--src | |--strlib | |--demo 第一、编写平台对应的编码代码。 汇给代码文件以如下格式的命名:asm_$ARCH.s (asm_386.s, asm_amd64.s, asm_arm.s, ...),我的环境是Ubuntu 12.04 LTS amd64架构. $ GOPATH=<youpath>/asm_demo $ cd $GOPATH $ cat <<EOF > src/strlib/asm_amd64.s TEXT .Equal(SB),7,$0 MOVL len+8(FP), BX MOVL len1+24(FP), CX MOVL $0, AX CMPL BX, CX JNE eqret MOVQ p+0(FP), SI MOVQ q+16(FP), DI CLD REP; CMPSB MOVL $1, DX CMOVLEQ DX, AX eqret: MOVB AX, ret+32(FP) RET EOF 本段代码来自 $GOROOT/src/pkg/bytes/asm_amd64.s 可以看出

Linux下嵌入汇编代码调用API(using fork())

狂风中的少年 提交于 2020-03-02 04:23:32
以下关于fork()的描述来自于: jason314 首先,在Linux环境下,一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。 fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值: 1)在父进程中,fork返回新创建子进程的进程ID; 2)在子进程中,fork返回0; 3)如果出现错误(如系统资源不足),fork返回一个负值。 在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。 现在,我们来写一段程序,使用API调用fork: #include <stdio.h> #include <unistd.h> int main() { pid_t fpid; int count = 0; fpid = fork(); printf("Now pid = %d\n", fpid); if(fpid < 0) printf("Error in fork!"); else if(fpid == 0){ printf("I am the

高精度乘法程序设计汇编语言版-课程设计

一笑奈何 提交于 2020-03-01 14:59:26
一段尘封已久的代码,当年的课程设计!高精度乘法程序设计汇编语言版 1.1 课程设计题目 高精度乘法程序设计 1.2 课程设计目的 1. 巩固和加深课堂所学知识 2. 将课本上的理论知识和实际应用有机的结合起来,培养同学们分析和解决实际问题的能力 3. 通过对汇编语言程序代码的阅读、修改、设计,理解和掌握复杂的汇编语言应用程序的编程,提高实践编程能力 1.3 程序运行环境及开发工具 本程序主要在装有Windows XP的PC机上利用MASM1的软件来实现。 1.4 程序功能使用说明 运行该程序后,根据提示信息输入形如:–256 * 65536 = 的格式,当键入 ‘ = ’后自行在‘ = ’后输出运算结果,当输入: 1. 输入操作数过程中输入多个符号; 2. 输入‘ = ’前未输入两操作数; 3. 输入‘ * ’前无操作数输入; 4. 输入非法操作数、非法操作符 等 程序会进行出错处理,提示输入错误,要求重新输入。 1.5 关键算法: 1.十进制转化为二进制 ASCII码→二进制数(用于输入) 因键入为整数,故要进行如下转换: ASCII→BCD→二进制数 1. ASCII→BCD码 将十进制数转换成BCD码要经过以下三步: 1. 取ASCII码的低四位(即十进制数的BCD码表示)。可用指令有(设ASCII码放在AL中):  SUB AL,30H 或 AND AL,0FH 2.

X86_64平台下32位汇编语言调用C库函数程序的汇编与链接

百般思念 提交于 2020-02-28 23:42:27
声明:转载请注明原链接 http://my.oschina.net/u/1167407/blog/484426 ‍‍‍今天在看《Professional Assembly Language》一书的第四章的Using C Library Functions in Assembly一节时,由于我使用的是64位的Linux系统,所以遇到了一些问题,其中有些挺有用的信息。所以,记录下来以免遗忘。‍ Using C Library Functions in Assembly这一小节介绍了如何在汇编程序中调用C的库函数。书中给出的示例代码如下:‍‍ .section .data output: .asciz “The processor Vendor ID is ‘%s’\n” .section .bss .lcomm buffer, 12 .section .text .globl _start _start: movl $0, %eax cpuid movl $buffer, %edi movl %ebx, (%edi) movl %edx, 4(%edi) movl %ecx, 8(%edi) pushl $buffer pushl $output call printf addl $8, %esp pushl $0 call exit 接下来使用gnu as汇编这段程序

C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一)

為{幸葍}努か 提交于 2019-12-23 12:52:48
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Constructs a closure: an unnamed function object capable of capturing variables in scope. —— Lambda functions (since C++11) [cppreference.com] 按照C++11标准的说法,lambda表达式的标准格式如下: [ capture ] ( params ) mutable exception attribute -> ret { body } // (1) 完整的声明 [ capture ] ( params ) -> ret { body } //(2) 一个常lambda的声明:按副本捕获的对象不能被修改。 [ capture ] ( params ) { body } // (3) 省略后缀返回值类型:闭包的operator()的返回值类型是根据以下规则推导出的:如果body仅包含单一的return语句,那么返回值类型是返回表达式的类型(在此隐式转换之后的类型:右值到左值、数组与指针、函数到指针)否则,返回类型是void [ capture ] { body } //(4) 省略参数列表:函数没有参数,即参数列表是() capture -

C++11新特性中的匿名函数Lambda表达式的汇编实现分析(三)

此生再无相见时 提交于 2019-12-23 12:44:58
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一) C++11新特性中的匿名函数Lambda表达式的汇编实现分析(二) Lambda表达式中较复杂的形式如下: [ capture ] ( params ) -> ret { body } 现在我们构造一个简单的Lambda闭包函数进行分析: int main() { int c = 10; auto lambda = [&] (int a, int b)->int{ return a + b - c; }; int r = lambda(1, 2); return 0; } 上面的代码中,lambda表达式要求传递两个参数a和b,并按引用捕获c,计算后的结果返回给r。 相应的汇编码如下: int c = 10; mov dword ptr [ebp-8],0Ah auto lambda = [&] (int a, int b)->int{ return a + b - c; }; lea eax,[ebp-8] push eax lea ecx,[ebp-14h] call 010E13B0 int r = lambda(1, 2); push 2 push 1 lea ecx,[ebp-14h] call 010E1400 mov dword

【汇编】C++ 函数调用之——有参无返回调用(传值)

こ雲淡風輕ζ 提交于 2019-12-10 04:01:09
C++函数有参调用有几种传参方式: 一.传值 二.传指针(地址) 三.传引用 其中参数可被const修饰,也可以有默认值。下面分情况讨论: 为了简洁,省略main函数的汇编码而直接给出func函数的汇编码。 一.传值调用 有源代码: void func(int a,char b){ int c; c=a+b; } int main(int argc,char *argv[]) { //call func func(10,'a'); return 0; } 下面看看汇编码: 调用发生时: //call func func(10,'a'); //进行参数压栈操作,首先是'a'压入栈,然后是10压栈,然后call跳转表,再由调转表call函数 00F1141E push 61h 00F11420 push 0Ah 00F11422 call 00F1113B //函数调用完成后,栈减小8字节,两个dword,因为CPU对栈的操作都是双字操作,这里两个参数就是两个双字 00F11427 add esp,8 具体内存中的表现是这样的(先让func把栈初始化): 显然不在func的stack内,注意两个参数前面还有两个DWORD, 一个是00f1 1427,另一个是00dd f794;这两个DWORD的产生应该是在PUSH两个参数之后, 又有的两个PUSH, 显然,第一个PUSH 00f1