linux 0.11笔记

  1. 47–56 行作用是将自身(bootsect)从目前段位置 0x07c0(31k)
    ! 移动到 0x9000(576k)处,共 256 字(512 字节),然后跳转到
    ! 移动后代码的 go 标号处,也即本程序的下一语句处
45 entry start ! 告知连接程序,程序从 start 标号开始执行。
46 start: ! 47--56 行作用是将自身(bootsect)从目前段位置 0x07c0(31k)
          ! 移动到 0x9000(576k)处,共 256 字(512 字节),然后跳转到
          ! 移动后代码的 go 标号处,也即本程序的下一语句处。
47 mov ax,#BOOTSEG ! 将 ds 段寄存器置为 0x7C0;
48 mov ds,ax
49 mov ax,#INITSEG ! 将 es 段寄存器置为 0x9000;
50 mov es,ax
51 mov cx,#256 ! 移动计数值=256 字;
52 sub si,si ! 源地址 ds:si = 0x07C0:0x0000
53 sub di,di ! 目的地址 es:di = 0x9000:0x0000
54 rep ! 重复执行,直到 cx = 0
55 movw ! 移动 1 个字;
      

ds:[0] ds:[si] si寄存器相当于通用寄存器。sub si,si,是si - si , 使得si为0,相当于mov si,0: sub di,di 也一样 ,真正的地址是CS16+IP 就是cpu要执行的指令,CS 存放要被cpu执行的代码的基地址 code segment ,IP 别名为指令指针寄存器,存放段地址的偏移地址*
如何把一段汇编代码拷贝到指定的内存位置?
可以用loop指令语句来实现,但是该语句比较繁琐,不太合适。
汇编语言提供rep和movsb指令实现相同的功能。
movsb指令:
字节传送指令:指令在存储单元之间传送字符串
使用movsb指令时ds:si指向了要拷贝字符串的首地址,es:di指向了要拷贝的目的地址。
cld指令拷贝数据的方向是从低字节往高字节拷贝,也就是说每拷贝一个字节si和di加1。
std指令和cld相反。
参考链接:https://www.cnblogs.com/magic-cube/archive/2011/10/19/2217654.html
bootsect.s参考:https://blog.csdn.net/longintchar/article/details/79323783
各种寄存器介绍:http://www.cnblogs.com/wisehead/articles/3819233.html
在这里插入图片描述
2.嵌入式汇编知识:
插入c语言的汇编可以分为4个部分,已:进行分割。一般形式如下:
指令部:输出部:输入部:损坏部
static inline void atomic_add(int i, atomic_t *v)

{

__asm_volatile__(

           LOCK "addl %1, %0"/*指令部,%0是从输出部顺序往下*/

           : "=m" (v->counter)  /*输出部分*/

           : "ir" (i), "m" (v->counter));/*输入部分*/

}
这段代码的作用是将参数i的值加到v->counter上。
指令部

数字加上前缀%,如%1、%0等,表示需要使用寄存器的样板操作数。可以使用的此类操作数的总数取决于具体CPU中通用寄存器的数量。

输出部

规定对输出变量,即目标操作数如何结合的约束条件。每个这样的条件称为一个“约束条件”。必要时输出部可以有多个约束条件,互相以逗号分隔。每个输出约束以“=”号开头,然后是一个字母表示对操作数类型的说明,然后是关于变量结合的约束。例子中:

: “=m” (v->counter)

这里只有一个约束条件,“=m”表示相应的目标操作数(指令中的%0)是一个内存单元v->counter。

输入部

输入部约束的格式和输出约束相似,但不带“=”号。例子中:

第1个为"ir" (i),表示指令中的%1可以是一个在寄存器中的“直接操作数”(i表示immediate),并且该操作数来自于C代码中的变量名(这里是调用参数)i。

第2个约束条件“m” (v->counter)意义与输入约束相同。

损坏部

有些操作中,除了用于输入操作数和输出操作数的寄存器外,还要将若干个寄存器用于计算或者操作的中间结果。这样,这些寄存器原有的内容就损坏了,所以要在损坏部对操作的副作用加以说明,让gcc采取相应的措施。不过,有的时候就直接把这些说明放在输出部了,那也并无不可。

操作数的编号从输出部的第一个约束(序号为0)开始,顺序数下来,每个约束计数加1次。在指令部中引用这些操作数或分配用于这些操作数的寄存器时,就在序号前面加上%号。
#define get_seg_byte(seg,addr) ({
register char __res;
asm( “push %%fs;mov %%ax,%%fs;movb %%fs:%2,%%al;pop %%fs”
: “=a” (__res): “” (seg), “m” ((addr)));
__res;})
(movb %%fs:%2,%%al )一句中是把以fs为段地址,以后面的第三号寄存器即后面的
(*addr)中的值为偏移地址所对应的值装入al。

#define do_div(n,base) ({
int __res;
asm( “divl %4” : “=a” (n), “=d” (__res): “0” (n), “1” (0), “r” (base));
38 __res; })

“0”表示使用与上面相同位置上的输出寄存器,“1”同理
参考文档:
https://blog.csdn.net/robbie1314/article/details/6329329
3.sed命令:
sed:Stream Editor文本流编辑,sed是一个“非交互式的”面向字符流的编辑器。能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上。还可以对原文件改动,但是不会再屏幕上返回结果。

sed命令的语法格式:

sed的命令格式: sed [option] 'sed command’filename

sed的脚本格式:sed [option] -f 'sed script’filename
参考文档:
https://www.cnblogs.com/ctaixw/p/5860221.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值