Tag: 程序集

浪费内存分配局部变量

这是我的计划: void test_function(int a, int b, int c, int d){ int flag; char buffer[10]; flag = 31337; buffer[0] = ‘A’; } int main() { test_function(1, 2, 3, 4); } 我用debug选项编译这个程序: gcc -g my_program.c 我使用gdb并使用intel语法反汇编test_function: (gdb) disassemble test_function Dump of assembler code for function test_function: 0x08048344 : push ebp 0x08048345 : mov ebp,esp 0x08048347 : sub […]

玩具OS文件系统

我在assembly / c中开发了一个运行基本终端的基本内核。 我把它设置为用grub运行iso。 我想继续这个操作系统,但没有文件系统,我觉得好像没有别的我能做的。 经过很长一段时间在互联网上,我已经想出了实现这一点我真的无能为力。 人们已经说过实现FAT或制作VFS,但没有任何进一步的,也没有教程,也没有任何参考。 有人可以解释文件系统如何工作,我可以在哪里开始/我可以连接预制系统,以及如何使用它? 另外,在编译我的操作系统时,我无法访问标准库。 我使用gcc,nasm,ld和grub-mkrescue(用于磁盘映像)。 我使用qemu进行模拟。 编辑减少OT 有人可以详细描述文件系统的工作原理,所以当我查看已经实现的文件系统的来源(如FAT)时,我能理解如何将它应用到我自己的操作系统中吗? 编辑 – 更简单 更容易。 我怎么能直接访问硬盘? 我的内核完全在保护模式下运行,因此我可以切换并直接写入硬盘驱动器。 可以使用如下文件实现文件系统: name 特殊字符 文本 特殊字符 即: hello world.script 0x00 println“Hello,world !!” 为0x00 在您不需要特殊分段的地方,您只需查看文件名和特殊字符(不是像’\ 0’这样的字符串中),然后读取,直到找到第二个非字符串字符。 是否有办法通过切入和退出保护模式或写入硬盘驱动器来实现这一点?

自动assembly循环级别分析

有谁知道任何汇编循环级别分析器? 我一直在使用gprof,但gprof隐藏了循环,它是function级别的分析,但为了优化我的代码,我想要一些东西进入循环级别。 我想让它自动化,只需给我输出像gprof。 我被建议去dtrace但我不知道要开始。 无论如何,任何人都可以指导我吗? 例如 main: pushl %ebp movl %esp, %ebp subl $16, %esp movl $5000000, -4(%ebp) movl $0, -12(%ebp) movl $0, -8(%ebp) jmp .L2 .L3: movl -8(%ebp), %eax addl %eax, -12(%ebp) addl $1, -8(%ebp) .L2: movl -8(%ebp), %eax cmpl -4(%ebp), %eax jl .L3 movl $0, %eax leave ret 例如在gprof中它会说主执行1次而foo执行100次。 但我想知道L2或L3是否执行了1M次,那么我对优化的专注就在这里。 如果我的问题含糊不清,请让我解释一下谢谢

如何使用在同一CPU上运行的调试器读取CPU寄存器?

当我学习汇编时,我使用GDB的方式如下: gdb ./a.out (a is a compiled C script that only prints hello world) break main run info registers 当我自己使用相同的CPU打印寄存器时,为什么还能看到程序使用的寄存器? 不应该使用GDB(或操作系统)覆盖寄存器,只显示覆盖的寄存器? 我能想到的唯一答案是我的CPU是双核的,其中一个核正在使用,另一个是为程序保留的。

C / C ++中的简单“Hello World”内联汇编语言程序

我用devcpp和borland c编译器…. asm { mov ax,4 // (I/O Func.) mov bx,1 // (Output func) mov cx,&name // (address of the string) mov dx,6 // (length of the string) int 0x21 // system call } 在上面的代码片段中,我想在汇编语言的帮助下打印一个字符串…但是如何将字符串的地址放在寄存器cx …. 代码中有什么问题???

如何在程序中包含数据对象文件(图像等)并访问符号?

我使用objcopy将几个资源文件转换为.obj文件,然后将它们与我的程序源代码链接起来。 我可以使用以下代码很好地访问程序中目标文件内的符号,但只能使用GCC / G ++(Cygwin): extern uint8_t data[] asm(“_binary_Resources_0_png_start”); extern uint8_t size[] asm(“_binary_Resources_0_png_size”); extern uint8_t end[] asm(“_binary_Resources_0_png_end”); 该代码在Visual Studio中不起作用,可能是因为VS拥有自己的__asm命令。 我希望通过链接它们将我的程序资源(图像,着色器等)包含在我的最终可执行文件的.data部分中。 但是如何在VC ++中访问目标文件中定义的符号? 我在没有汇编命令的情况下尝试了extern uint8_t _binary_Resources_0_png_start[]或extern “C” uint8_t _binary_Resources_0_png_start[] ,但是我得到了未解决的符号链接错误。

编译器用a 做什么?a是数组? 如果a是指针怎么办?

c-faq告诉我,编译器在处理a [i]时做了不同的事情,而a是数组或指针。 这是c-faq的一个例子: char a[] = “hello”; char *p = “world”; 鉴于上面的声明,当编译器看到表达式a [3]时,它会发出代码从位置“a”开始,移动三个,然后在那里获取字符。 当它看到表达式p [3]时,它会发出代码从位置“p”开始,在那里获取指针值,向指针添加三个,最后获取指向的字符。 但有人告诉我,在处理[i]时,编译器倾向于将a(这是一个数组)转换为指向数组的指针。 所以我想查看汇编代码以找出哪个是正确的。 编辑: 这是本声明的来源。 c-faq并注意这句话: formsa [i]的表达式导致数组衰减成指针,遵循上面的规则,然后被下标,就像表达式p [i]中的指针变量一样(尽管最终的内存访问将是不同,“ 我对此很困惑:既然a已经衰减到指针,那为什么他的意思是“内存访问会有所不同?” 这是我的代码: // array.cpp #include using namespace std; int main() { char a[6] = “hello”; char *p = “world”; printf(“%c\n”, a[3]); printf(“%c\n”, p[3]); } 这是我使用g ++ -S array.cpp获得的汇编代码的一部分 .file “array.cpp” .section .rodata […]

了解有关i ++和i = i + 1的更多信息

我想知道两种增量forms之间是否存在差异。 一些链接说i ++比i = i + 1更快; 另外作为人之一,我的观察对于汇编代码也是一样的。 请检查图像,其中汇编代码对于i ++和i = i + 1都是相同的 – 还有另一个链接说以前曾经是真的,增量运算符比加法和赋值更快,但现在编译器优化i ++和i = i + 1相同。 是否有任何官方文件/文件我们可以参考确认什么是正确的? (我通常会使用信用卡和一个人在stackoverflow上接受的答案数量。在我提供的链接上找不到任何此类信息)。

我怎么知道gcc是否同意某些东西是不稳定的?

考虑以下: volatile uint32_t i; 我如何知道gcc是否确实将我视为易变? 它将被声明为是因为没有附近的代码将修改它,并且它的修改可能是由于某些中断。 我不是世界上最差的汇编程序员,但我在电视上播放一个。 有人可以帮我理解它会有什么不同吗? 如果你采取以下愚蠢的代码: #include #include volatile uint32_t i; int main(void) { if (i == 64738) return 0; else return 1; } 将其编译为对象格式并通过objdump反汇编,然后在删除’volatile’后执行相同操作,没有区别(根据diff)。 volatile声明是否太接近于其检查或修改的位置,或者我在声明易失性时应该总是使用某种primefaces类型? 一些优化标志会影响这个吗? 请注意,我的愚蠢样本并不完全符合我的问题,我意识到这一点。 我只是试图找出gcc是否确实将变量视为易失性,所以我正在研究小型转储以试图找到差异。

利用LDT(本地描述符表)

我试图使用除默认代码和数据用户和内核段之外的不同段进行一些实验。 我希望通过使用本地描述符表和modify_ldt系统调用来实现这一点。 通过系统调用,我在LDT中创建了一个新条目,它是一个段描述符,其基地址是我要“隔离”的全局变量,限制为4个字节。 我尝试通过C程序中的内联汇编将数据段寄存器与我的自定义LDT条目的段选择器一起加载,但是当我尝试访问变量时,我收到了分段错误。 我的怀疑是我的全局变量的偏移存在问题,并且在计算地址时,它超出了我的自定义段的限制,因此导致seg错误。 有谁知道这种情况的工作? 哦,顺便说一句,这是在Linux上的x86架构上。 这是我第一次在论坛上提出这样的问题,所以如果有任何其他信息可以certificate是有用的,请告诉我。 先感谢您。 编辑:我意识到我可能应该包含源代码:) struct user_desc* table_entry_ptr = NULL; /* Allocates memory for a user_desc struct */ table_entry_ptr = (struct user_desc*)malloc(sizeof(struct user_desc)); /* Fills the user_desc struct which represents the segment for mx */ table_entry_ptr->entry_number = 0; table_entry_ptr->base_addr = ((unsigned long)&mx); table_entry_ptr->limit = 0x4; table_entry_ptr->seg_32bit = 0x1; table_entry_ptr->contents = […]