Articles of x86

Memcpy与memset相同

我想用memcpy来测量内存带宽。 我从这个答案修改了代码: 为什么vector化循环没有使用memset来衡量带宽的性能改进 。 问题是memcpy只比memset稍慢,因为我认为memcpy运行速度是内存两倍以上的两倍。 更具体地说,我运行了超过1 GB的数组a和b (分配将calloc )100次,执行以下操作。 operation time(s) —————————– memset(a,0xff,LEN) 3.7 memcpy(a,b,LEN) 3.9 a[j] += b[j] 9.4 memcpy(a,b,LEN) 3.8 请注意, memcpy只比memset慢一点。 a[j] += b[j] (其中j越过[0,LEN) )的操作应该比memcpy长三倍,因为它操作的数据量是三倍。 但是它只有memset 2.5左右。 然后我用memset(b,0,LEN)将b初始化为零并再次testing: operation time(s) —————————– memcpy(a,b,LEN) 8.2 a[j] += b[j] 11.5 现在我们看到, memcpy大约是memset两倍, a[j] += b[j]大约是memset三倍。 至less我会预期,在memset(b,0,LEN) , memcpy会比较慢,因为 100次迭代中的第一次迭代的延迟分配(第一次触发) 。 为什么我只能在memset(b,0,LEN)之后得到预期的时间? test.c的 #include <time.h> […]

C调用约定并传递参数

在Linux(或OS X)中进行函数调用时,被调用者是否可以修改堆栈中参数的值? 我是在这样的假设下,因为调用者是清理它们的那个,所以在函数调用之后它们应该包含相同的值。 但是我发现使用-O2的GCC正在修改传递给堆栈的参数。 我还查找了包括System V i386调用约定的文档,但无法find明确的答案。 这是我正在debugging的一些示例代码。 pushl %eax # %eax = 0x28 call _print_any popl %eax # %eax is now 0x0a 我会假设GCC修改堆栈上的参数是好的,但我想知道它在哪里指定它可以这样做。

在x86中将string定义为字节(db)和将string定义为字/双字(dw / dd)有什么区别?

我试图调查大会定义标签之间的差异,这里是一个例子 ALabel: db 'Testing' AAnotherLabel: dw 'Testing' 现在,让我加载到一个32位寄存器: mov eax, [ALabel] mov ebx, [AAnotherLabel] 经过gdb的调查,我发现eax和ebx的所有子寄存器都包含相同的值,请看这里: info register eax 0x64636261 //dcba info register ebx 0x64636261 //dcba 他们是一样的! 在Jeff Duntemann的书中(汇编语言使用Linux进行分步编程),他给出了一个单词和双字进入寄存器的例子,但由于某种原因加载了偏移量(即像这样的值的地址) DoubleString: dd 'Stop' mov edx, DoubleString 对edx内容的调查显示,它包含一个地址,可能是string中前四个字母的地址,与第一个地址相同,尽pipe我在这里进行了推测。 我想澄清在这里真正发生了什么,并且这个声明实际上是将string中第一个字母的地址加载到一个寄存器中: Fin: db 'Final' mov ecx, Fin

汇编语言中的分割错误

我正在学习AT&T x86汇编语言。 我试图编写一个汇编程序,它采用整数n,然后返回结果(n / 2 + n / 3 + n / 4)。 这是我所做的: .text .global _start _start: pushl $24 call profit movl %eax, %ebx movl $1, %eax int $0x80 profit: popl %ebx popl %eax mov $0, %esi movl $4, %ebp div %ebp addl %eax, %esi movl %ecx, %eax movl $3, %ebp div %ebp addl […]

有没有错误列表会显示为“segfaults”,当他们没有真正的内存访问?

在这个问题中 ,我了解到,如果不在响铃0时尝试运行特权指令,可能会导致在用户进程中看起来像段错误,并有两个后续问题。 所有特权指令都是如此吗? 还有什么其他types的错误会导致假段错误,但与试图读取内存无关?

汇编语言计算器 – Linux x86&NASM – Division

我正在用汇编语言编写一个计算器,以在x86处理器上执行。 基本上,我的计算器要求用户input两个数字,然后指出哪个操作(加法,减法,乘法和除法)要与他们做。 我的计算器加减乘法正确但无法分割 。 在划分时,我总是得到1。 然后我离开我的应用程序代码完成: section .data ; Messages msg1 db 10,'-Calculator-',10,0 lmsg1 equ $ – msg1 msg2 db 10,'Number 1: ',0 lmsg2 equ $ – msg2 msg3 db 'Number 2: ',0 lmsg3 equ $ – msg3 msg4 db 10,'1. Add',10,0 lmsg4 equ $ – msg4 msg5 db '2. Subtract',10,0 lmsg5 equ $ – […]

Linux x86:实模式地址空间在受保护的内核模式下映射到哪里?

在x86平台上运行的Linux中,实模式地址空间是在受保护的内核模式下映射到的吗? 在内核模式下,一个线程可以直接访问内核地址空间。 内核处于低8MB,页表处于某个位置等(如此处所述)。 但是实模式地址空间在哪里呢? 可以直接访问吗? 例如BIOS和BIOS插件(见这里 )?

如何获得中断向量?

当我运行“cat / proc / interrupts”时,我可以得到以下结果: CPU0 CPU1 0: 253 1878 IO-APIC-edge timer 1: 3 0 IO-APIC-edge i8042 7: 1 0 IO-APIC-edge parport0 8: 0 1 IO-APIC-edge rtc0 9: 0 0 IO-APIC-fasteoi acpi 12: 1 3 IO-APIC-edge i8042 16: 681584 60 IO-APIC-fasteoi uhci_hcd:usb3, nvidia 17: 0 0 IO-APIC-fasteoi uhci_hcd:usb4, uhci_hcd:usb7 18: 0 0 IO-APIC-fasteoi uhci_hcd:usb8 22: […]

读取GDB寄存器指向的内存

如果知道内存位置,有没有办法从GDB查看内存内容? 那是我正在debugging我为我的操作系统课程编写的x86汇编程序。 我正在尝试做的是用C和gas(GNU汇编器)在x86上编写用于Linux的用户级线程库。 我分配了自己的堆栈,并将esp寄存器指向了该内存位置。 现在我想要做的是读取内存,看看我分配的堆栈里有什么。

linux nasm将AL中的值移至AX

我正在打印多个数字整数的方式,将整数除以10,然后收集剩下的部分,然后打印出来。 这是一个有问题的代码段: 划分: ; initial division mov ax, 111 ; number we want to print mov ch, 10 ; we divide by ten to siphon digits div ch ; divide our number by 10 ; al now has 11, ah has 1 mov dh, ah ; save the remainder in dh 1 mov bx, al […]