CPT101内联汇编课件详解

汇编(assembly)

前置知识

CPU中需要将数据或指令存入寄存器中才能对其进行操作。

地址个人理解(
数据都是存在内存中某一特定地址中, CPU访问内存时可以通过地址来获取某块内存上的数据
用来存放地址的变量, 我们称为指针, 不论何种数据类型(int, char, 结构体), 指向它所在地址的指针大小都为4字节, 所以下面的程序里弹栈操作我们会使其ESP寄存器(存放栈顶指针)加4(Intel系统中栈是向下生长的, 改变栈顶位置使其+4也就是实现一个弹栈操作)

但是弹栈时指针移动的长度是看使用的寄存器类型
EAX为32位寄存器, 其中数据的大小刚好是4字节, 所以每次移动栈顶指针都要使其+4
AX为EAX的低16位的 “ 子寄存器 ”
AL为EAX(或说AX)低8位的 “ 子寄存器 ”
AH为AX高八位的“ 子寄存器 ”

汇编关键字

赋值

LEA (load effective address)
lea eax, a 是将a的地址复制到寄存器eax

MOV (move)
mov eax, a 是将a的值赋值给寄存器eax

ADD 加法运算
add eax, a 是将eax中的值加上a

SUB 减法运算
sub eax, a 是将eax中的值减去a

PUSH 入栈
push esp 是将eap的地址入栈(先让堆栈指针加一, 再压栈)

CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).

JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).

简单比较大小汇编程序解读

int main()
{
    char message1[] = "Enter a first number";
    char message2[] = "\bGive me a second number: ";
    char message3[] = "\nThe numbers are equal!\n";
    char message4[] = "\nSecond is larger!\n";
    char message5[] = "\nFirst is larger";
    char message6[] = "Type in any integer and press ENTER key to finish: ";

    //scanf的读入整数的标志是%d
    char format[] = "%d";	// format string for the scanf function

    int first;
    int second;
    int end;

    _asm{
        ;1输出message1
        ;这里注意一下,lea是传递地址,c语言中字符数组message1是数组名,也是字符串的首地址
        ;实测改成message1[0]也能正常执行,如果改成message1[4],则前4个字符不会输出
            lea		eax, message1
            push	eax
            call	printf
            add		esp, 4
        ;2读入first
            lea		eax, first
            push	eax
            lea		eax, format
            push	eax
            call	scanf
            add		esp, 8
        ;3输出message2
            lea		eax, message2
            push	eax
            call	printf
            add		esp, 4
        ;4读入second
            lea		eax, second
            push	eax
            lea		eax, format
            push	eax
            call	scanf
            add		esp, 8
        ;5判断是否相等, 不相等则jump到less判断first是否小于second
            mov		eax, first
            sub		eax, second
            jnz		less
        ;6两数相等,没有跳过,输出message3,jump到finish
            equal:
            lea		eax, message3
            push	eax
            call	printf
            add		esp, 4
            jmp		finish
        ;7继承了5的状态,判断first是否小于second,不满足直接jump到large
            less:
            mov		eax, first
            sub		eax, second
            jl      larger
        ;8first小于second,没有跳过,输出message5,并jump到finish
            lea		eax, message5
            push	eax
            call	printf
            add		esp, 4
            jmp		finish
        ;9输出message4,first大于second
            larger:
            lea		eax, message4
            push	eax
            call	printf
            add		esp, 4
        ;10输出message6
            finish:
            lea		eax, message6
            push	eax
            call	printf
            add		esp, 4
        ;11等待输入下一个数,防止程序执行完毕自动退出
            lea		eax, end
            push	eax
            lea		eax, format
            push	eax
            call	scanf
            add		esp, 8
    }
    return 0;
}
  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值