【TakeLionOS第七课】TakeLionOS汇编与C语言自学笔记-第六课.rar
[TakeLionOS汇编与C语言自学笔记-第六课]
版权所有 2021年 江志剑
按照《21天学通C语言》(第七版),有如下一个例子P17。
将整个程序的代码,包括行号显示出来:
//1、files:hellolistit.c hellolistitno.s hellolistit.exe
/* hellolistit.c - 该程序将显示整个程序的代码,包括行号! */
#include <stdio.h>
#include <stdlib.h>
#define BUFF_SIZE 256
void display_usage(void);
int line;
int main(int argc, char *argv[])
{
char buffer[BUFF_SIZE];
FILE *fp;
if (argc < 2)
{
display_usage();
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
fprintf(stderr, "Error opening file, %s!", argv[1]);
return (1);
}
line = (1);
while (fgets(buffer, BUFF_SIZE, fp) != NULL)
fprintf(stdout,"%4d:\t%s", line++, buffer);
fclose(fp);
return 0;
}
void display_usage(void)
{
fprintf(stderr, "\nProper Usage is:");
fprintf(stderr, "\n\nhellolistit filename.ext\n");
}
我是用GCC 8.1.0在命令行窗口运行的。
GCC编译时候,其实有四个步骤:
1、预处理:gcc -E hello.c -o hello.i
2、编译生成汇编语言:gcc -S hello.i -o hello.s
3、汇编:gcc -c hello.s -o hello.o
4、链接生成可执行文件:gcc hello.o -o hello
这时候,我想看一下第二步生成的汇编语言代码。
因为本身就是研究操作系统的一部分,所以要研究底层的汇编语言。
结果发现是AT&T格式的汇编语言风格,而且大量使用汇编宏。
所以启用了GCC的编译选项-fno-asynchronous-unwind-tables,直接预处理为没有cfi宏的汇编指令。
这里就是包含*no.s形式的文件。
最后的LEAVE指令,等效于“MOV ESP,EBP”和“POP EBP”两条指令。
这个指令调整了数据栈指针ESP,并将EBP的数值恢复到调用这个函数之前的初始状态。
毕竟函数要在退出之前恢复这些寄存器的值。
问题是其中的注释中文字符,输出的时候会出现乱码?这个问题暂时解决不了。
用了-fexec-charset=gbk 和-finput-charset=gbk,也解决不了。
这里面汇编指令也有很多问题。
今天太迟了,就不继续下去了。
【TakeLionOS第六课】TakeLionOS汇编与C语言自学笔记-第五课.rar
[TakeLionOS汇编与C语言自学笔记-第五课]
版权所有 2021年 江志剑
按照《21天学通C语言》(第七版),有如下二个例子。
一个例子输出一段话,另一个例子计算年份:
//1、files:hello1.c hello1no.s hello1.exe
#include <stdio.h>
int main(void)
{
printf("This is an example of sometjing printed!");
return 0;
}
//2、files:helloyear.c helloyearno.s helloyear.exe
#include <stdio.h>
#define TARGET_AGE 88
int year1, year2;
int calcYear(int year1);
int main(void)
{
printf("What year was the subject born?");
printf("Enter as a 4-digit year (YYYY):");
scanf("%d", &year1);
year2 = calcYear(year1);
printf("Someone born in %d will be %d in %d.", year1, TARGET_AGE, year2);
return 0;
}
int calcYear(int year1)
{
return (year1 + TARGET_AGE);
}
我是用GCC 8.1.0在命令行窗口运行的。
GCC编译时候,其实有四个步骤:
1、预处理:gcc -E hello.c -o hello.i
2、编译生成汇编语言:gcc -S hello.i -o hello.s
3、汇编:gcc -c hello.s -o hello.o
4、链接生成可执行文件:gcc hello.o -o hello
这时候,我想看一下第二步生成的汇编语言代码。
因为本身就是研究操作系统的一部分,所以要研究底层的汇编语言。
结果发现是AT&T格式的汇编语言风格,而且大量使用汇编宏。
所以启用了GCC的编译选项-fno-asynchronous-unwind-tables,直接预处理为cfi宏的汇编指令。
这里就是包含*no.s形式的文件。
比较发现,第一个文件和第二个文件,关键看寄存器的使用以及子函数的调用。
还有就是全局变量的使用。
我们学习汇编语言,因为零基础不知道学习什么?所以先有个概念。
比如这时候,几节课下来,就知道了该认真学习寄存器的用法了。
这是一个基本概念,现在反复用到了。
最后的LEAVE指令,等效于“MOV ESP,EBP”和“POP EBP”两条指令。
这个指令调整了数据栈指针ESP,并将EBP的数值恢复到调用这个函数之前的初始状态。
毕竟函数要在退出之前恢复这些寄存器的值。
【TakeLionOS第五课】TakeLionOS汇编与C语言自学笔记-第四课.rar
[TakeLionOS汇编与C语言自学笔记-第四课]
版权所有 2021年 江志剑
按照《21天学通C语言》(第七版),有如下二个例子。其中一个改为输出黑桃符号,是练习题3修改一下的:
//1、files:helloxy.c helloxy.i helloxyno.s helloxy.exe
#include <stdio.h>
int x,y;
int main(void)
{
for (x = 0; x < 10;x++, printf("\n"))
for ( y = 0; y < 10; y++)
printf("X");
return 0;
}
//2、files:helloxyq.c helloxyq.i helloxyqno.s helloxyq.exe
#include <stdio.h>
int x,y;
int main(void)
{
for (x = 0; x < 10;x++, printf("\n"))
for ( y = 0; y < 10; y++)
printf("%c",6);
return 0;
}
我是用GCC 8.1.0在命令行窗口运行的。
GCC编译时候,其实有四个步骤:
1、预处理:gcc -E hello.c -o hello.i
2、编译生成汇编语言:gcc -S hello.i -o hello.s
3、汇编:gcc -c hello.s -o hello.o
4、链接生成可执行文件:gcc hello.o -o hello
这时候,我想看一下第二步生成的汇编语言代码。
因为本身就是研究操作系统的一部分,所以要研究底层的汇编语言。
结果发现是AT&T格式的汇编语言风格,而且大量使用汇编宏。
所以启用了GCC的编译选项-fno-asynchronous-unwind-tables,直接预处理为cfi宏的汇编指令。
这里就是包含*no.s形式的文件。
比较发现,第一个文件和第二个文件,其余基本一样,但是第20行不一样了:
helloxy.s:movl $88, (%esp) //大写X
helloxyq.s:movl $6, (%esp) //黑桃
也没有出现.ascii宏,因为不是输出字符串了,而是输出字符X和黑桃符号。
最后的LEAVE指令,等效于“MOV ESP,EBP”和“POP EBP”两条指令。
这个指令调整了数据栈指针ESP,并将EBP的数值恢复到调用这个函数之前的初始状态。
毕竟函数要在退出之前恢复这些寄存器的值。
【TakeLionOS第四课】TakeLionOS汇编与C语言自学笔记-第三课.rar
[TakeLionOS汇编与C语言自学笔记-第三课]
版权所有 2021年 江志剑
按照《21天学通C语言》(第七版),有如下二个修改版的例子。其中一个改为输出黑桃符号,其中一个改为输出红心符号,是练习题6修改一下的:
//1、files:helloqq.c helloqq.i helloqq.s helloqqno.s helloqq.exe
#include <stdio.h>
int main(void)
{
printf("%c",6);
return 0;
}
//2、files:helloq.c helloq.i helloq.s helloqno.s helloq.exe
#include <stdio.h>
int main(void)
{
printf("%c",3);
return 0;
}
我是用GCC 8.1.0在命令行窗口运行的。
GCC编译时候,其实有四个步骤:
1、预处理:gcc -E hello.c -o hello.i
2、编译生成汇编语言:gcc -S hello.i -o hello.s
3、汇编:gcc -c hello.s -o hello.o
4、链接生成可执行文件:gcc hello.o -o hello
这时候,我想看一下第二步生成的汇编语言代码。
因为本身就是研究操作系统的一部分,所以要研究底层的汇编语言。
结果发现是AT&T格式的汇编语言风格,而且大量使用汇编宏。
这里就是不包含*no.s形式的文件。
所以启用了GCC的编译选项-fno-asynchronous-unwind-tables,直接预处理为cfi宏的汇编指令。
这里就是包含*no.s形式的文件。
比较发现,第一个文件和第二个文件,其余基本一样,而且第12行开始的调用函数完全一样了:
helloqq.s:call _putchar
helloq.s:call _putchar
也没有出现.ascii宏,因为不是输出字符串了,而是输出黑桃和红心符号。
唯一差别就是第12行:movl $6, (%esp)和movl $3, (%esp)
这样就能开始领会汇编语言的奥妙,开始学到汇编语言了。因为其他都是一样的,照抄即可。
最后的LEAVE指令,等效于“MOV ESP,EBP”和“POP EBP”两条指令。
这个指令调整了数据栈指针ESP,并将EBP的数值恢复到调用这个函数之前的初始状态。
毕竟函数要在退出之前恢复这些寄存器的值。
【TakeLionOS第三课】TakeLionOS汇编与C语言自学笔记-第二课.rar
按照《21天学通C语言》(第七版),有如下二个例子。其中一个改为输出红心符号,是练习题6修改一下的:
//1、files:hello.c hello.i hello.s hellono.s hello.exe
#include <stdio.h>
int main(void)
{
printf("Hello, World!");
return 0;
}
//2、files:helloq.c helloq.i helloq.s helloqno.s helloq.exe
#include <stdio.h>
int main(void)
{
printf("%c",3);
return 0;
}
我是用GCC 8.1.0在命令行窗口运行的。
GCC编译时候,其实有四个步骤:
1、预处理:gcc -E hello.c -o hello.i
2、编译生成汇编语言:gcc -S hello.i -o hello.s
3、汇编:gcc -c hello.s -o hello.o
4、链接生成可执行文件:gcc hello.o -o hello
这时候,我想看一下第二步生成的汇编语言代码。
因为本身就是研究操作系统的一部分,所以要研究底层的汇编语言。
结果发现是AT&T格式的汇编语言风格,而且大量使用汇编宏。
这里就是不包含*no.s形式的文件。
所以启用了GCC的编译选项-fno-asynchronous-unwind-tables,直接预处理为cfi宏的汇编指令。
这里就是包含*no.s形式的文件。
比较发现,第一个文件和第二个文件,其余基本一样,但是第12行开始的调用函数完全不一样了:
hello.s:call _printf
helloq.s:call _putchar
也没有出现.ascii宏,因为不是输出字符串了,而是输出红心符号。
最后的LEAVE指令,等效于“MOV ESP,EBP”和“POP EBP”两条指令。
这个指令调整了数据栈指针ESP,并将EBP的数值恢复到调用这个函数之前的初始状态。
毕竟函数要在退出之前恢复这些寄存器的值。
【TakeLionOS第二课】[TakeLionOS汇编与C语言自学笔记-第一课].rar
按照《21天学通C语言》(第七版),有如下三个例子。其中一个改为输出中文:
//1、files:hello.c hello.i hello.s hellono.s hello.exe
#include <stdio.h>
int main(void)
{
printf("Hello, World!");
return 0;
}
//2、files:hello1.c hello1.i hello1.s hello1no.s hello1.exe
#include <stdio.h>
int main(void)
{
printf("This is an example of sometjing printed!");
return 0;
}
//3、files:hellocn.c hellocn.i hellocn.s hellocnno.s hellocn.exe
#include <stdio.h>
int main(void)
{
printf("这样打印输出一个字符 , %c\n 一个数字 , %d\n 一个浮点数字 , %f", 'z', 123,456.789);
return 0;
}
如果直接编译运行,则为出现乱码。
怎么解决中文乱码?
然后观察三个文件的汇编语言版本的差异。
从中学习汇编与C语言知识。
【TakeLionOS第一课】用物理U盘写入MBR直接启动hackos.rar
一般自制操作系统的书籍资料,都是采用虚拟机或者软盘实现。
时下几乎见不到软盘了,而虚拟机也没有真实感。
能不能直接在物理U盘上写入MBR,实现物理U盘启动呢?
有些人尝试过,会出现乱码。
我尝试了几次,如果不采用显卡实现,可能会出现乱码。
用到NASM,DD,NOTEPAD++,汇编语言实现显示:
Hi MBR by JZJ
可谓是最小的操作系统,只有512B。