以下所有说明都做同样的事情:设置%eax为零.哪种方式最佳(需要最少的机器周期)?
xorl %eax, %eax
mov $0, %eax
andl $0, %eax
Run Code Online (Sandbox Code Playgroud) 我使用英特尔®架构代码分析器(IACA)发现了一些意想不到的东西(对我而言).
以下指令使用[base+index]寻址
addps xmm1, xmmword ptr [rsi+rax*1]
Run Code Online (Sandbox Code Playgroud)
根据IACA没有微熔丝.但是,如果我用[base+offset]这样的
addps xmm1, xmmword ptr [rsi]
Run Code Online (Sandbox Code Playgroud)
IACA报告它确实融合了.
英特尔优化参考手册的第2-11节给出了以下"可以由所有解码器处理的微融合微操作"的示例
FADD DOUBLE PTR [RDI + RSI*8]
Run Code Online (Sandbox Code Playgroud)
和Agner Fog的优化装配手册也给出了使用[base+index]寻址的微操作融合的例子.例如,请参见第12.2节"Core2上的相同示例".那么正确的答案是什么?
当我使用时nasm -f macho64 asm1.asm,出现以下错误:
asm1.asm:14: 错误:Mach-O 64 位格式不支持 32 位绝对地址
这是 asm1.asm
SECTION .data ;initialized data
msg: db "Hello world, this is assembly", 10, 0
SECTION .text ;asm code
extern printf
global _main
_main:
push rbp
mov rbp, rsp
push msg
call printf
mov rsp, rbp
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
我对汇编真的很陌生,几乎不知道这些命令的作用。知道这里有什么问题吗?
这是一个 OSX 链接器问题。我不认为 OSX(BSD 或 Mach 层)关心零页有多大或者它是否存在。我认为这是一个工具的事情。但这是我的意见,也是我提问的原因。
-pagezero_size 大小:默认情况下,链接器创建一个从地址零开始名为 __PAGEZERO 的不可读段。如果取消引用 NULL 指针,它的存在将导致总线错误。
这很清楚;它用于捕获 NULL 指针。在 32b OSX 系统上,段的大小为 4KB,这是系统页大小。但在当前的 64b 系统上,该段的大小增加到 4GB。为什么它不保持系统页面大小 4KB 或架构的最大页面大小 2MB?这意味着我根本无法使用 32b 绝对寻址。
使用此标志并覆盖默认值是否存在任何问题?苹果商店规定,...?
(此功能特定于 OSX ld64 链接器。该功能至少可以追溯到 2006 年 3 月 ld64-47.2。地址空间布局随机化和 64b 支持于 2007 年 10 月从 Leopard 开始。)
使用以下命令在我的Mac计算机上运行此代码:
nasm -f macho64 -o max.a maximum.asm
Run Code Online (Sandbox Code Playgroud)
这是我尝试在计算机上运行的代码,该代码在数组中找到最大的数字。
section .data
data_items:
dd 3,67,34,222,45,75,54,34,44,33,22,11,66,0
section .text
global _start
_start:
mov edi, 0
mov eax, [data_items + edi*4]
mov ebx, eax
start_loop:
cmp eax, 0
je loop_exit
inc edi
mov eax, [data_items + edi*4]
cmp eax, ebx
jle start_loop
mov ebx, eax
jmp start_loop
loop_exit:
mov eax, 1
int 0x80
Run Code Online (Sandbox Code Playgroud)
错误:
maximum.asm:14: error: Mach-O 64-bit format does not support 32-bit absolute addresses
maximum.asm:21: error: Mach-O 64-bit format does not support 32-bit absolute …Run Code Online (Sandbox Code Playgroud) 我创建使用NASM它调用一个简单的Hello World printf,并_exit从libc的,但不使用main.
extern printf
extern _exit
section .data
hello: db 'Hello world!',10
section .text
global _start
_start:
xor eax, eax
mov edi, hello
call printf
mov rax, 0
jmp _exit
Run Code Online (Sandbox Code Playgroud)
我像这样创建对象文件
nasm -felf64 hello.asm
Run Code Online (Sandbox Code Playgroud)
然后我可以使用动态链接与glibc这样链接它
ld hello.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64
Run Code Online (Sandbox Code Playgroud)
这运行正确,没有错误.但现在我想静静地做.我做
ln -s `gcc -print-file-name=libc.a`
ln -s `gcc -print-file-name=libgcc_eh.a`
ld hello.o -static libc.a libgcc_eh.a libc.a -melf_x86_64
Run Code Online (Sandbox Code Playgroud)
这链接,但当我运行代码时,我得到一个分段错误.使用gdb我看到它给出
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401004 in vfprintf ()
Run Code Online (Sandbox Code Playgroud)
如果我在C中编写一个简单的hello世界并在运行中使用static编译,那么显然可以在我的系统上静态链接到glibc.如何使用glibc与汇编代码进行静态链接?
如果我链接到glibc的替代品,如musl-libc, …
const struct mach_header *mach = _dyld_get_image_header(0);
struct load_command *lc;
struct segment_command_64 *sc64;
struct segment_command *sc;
if (mach->magic == MH_MAGIC_64) {
lc = (struct load_command *)((unsigned char *)mach + sizeof(struct mach_header_64));
printf("[+] detected 64bit ARM binary in memory.\n");
} else {
lc = (struct load_command *)((unsigned char *)mach + sizeof(struct mach_header));
printf("[+] detected 32bit ARM binary in memory.\n");
}
for (int i = 0; i < mach->ncmds; i++) {
if (lc->cmd == LC_SEGMENT) {
sc = (struct segment_command *)lc;
NSLog(@"32Bit: %s …Run Code Online (Sandbox Code Playgroud)