我在Linux x86_64上试验ELF可执行文件和gnu工具链:
我已经链接并剥离(手工)"Hello World"测试.:
.global _start
.text
_start:
mov $1, %rax
...
Run Code Online (Sandbox Code Playgroud)
到一个267字节的ELF64可执行文件...
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
0000010: 0200 3e00 0100 0000 d400 4000 0000 0000 ..>.......@.....
0000020: 4000 0000 0000 0000 0000 0000 0000 0000 @...............
0000030: 0000 0000 4000 3800 0100 4000 0000 0000 ....@.8...@.....
0000040: 0100 0000 0500 0000 0000 0000 0000 0000 ................
0000050: 0000 4000 0000 0000 0000 4000 0000 0000 ..@.......@.....
0000060: 0b01 0000 0000 0000 0b01 0000 …Run Code Online (Sandbox Code Playgroud) 我有一个我已经拆解的C++程序,看起来程序集正在使用指令指针获取字符串文字.例如:
leaq 0x15468(%rip), %rsi ## literal pool for: "special"
Run Code Online (Sandbox Code Playgroud)
和
leaq 0x15457(%rip), %rsi ## literal pool for: "ordinary"
Run Code Online (Sandbox Code Playgroud)
为什么编译器使用指令指针获取字符串文字?这似乎会导致任何人类程序员的头痛,尽管对编译器来说可能并不那么难.
不过,我的问题是为什么?有没有基于机器或历史的原因或编译器编写者是否决定%rip任意使用?
我正在尝试将“main”的地址加载到 GNU 汇编器中的寄存器 (R10) 中。我没办法。在这里,我有什么和我收到的错误消息。
main:
lea main, %r10
Run Code Online (Sandbox Code Playgroud)
我还尝试了以下语法(这次使用 mov)
main:
movq $main, %r10
Run Code Online (Sandbox Code Playgroud)
使用以上两种方法,我都会收到以下错误:
/usr/bin/ld: /tmp/ccxZ8pWr.o: relocation R_X86_64_32S against symbol `main' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
使用 -fPIC 编译不能解决问题,只会给我同样的错误。
我正在尝试在x86_64程序集中打印浮点数,但它只是将值打印为零.
关于这个问题已经存在一些问题.通过确保设置在%al中使用的向量寄存器的数量,似乎可以解决一个问题.另一个表明你需要一个16字节的堆栈对齐.但是,我正在做这两件事而仍然没有得到正确的输出.
这是我的计划:
# prints a floating point value
.section .rodata
.fmt: .string "num: %f\n"
.num: .float 123.4
.section .text
.global main
.type main, @function
main:
subq $8, %rsp # 16-byte alignment
# print my number
movss .num, %xmm0 # load float value
movq $.fmt, %rdi # load format string
movb $1, %al # use 1 vector register
call printf
# exit
addq $8, %rsp # undo alignment
movq $0, %rax # return 0
ret
Run Code Online (Sandbox Code Playgroud) 我正在按照本教程关于装配.
根据教程(我也在本地尝试,并得到类似的结果),以下源代码:
Run Code Online (Sandbox Code Playgroud)int natural_generator() { int a = 1; static int b = -1; b += 1; /* (1, 2) */ return a + b; }
编译到这些汇编指令:
Run Code Online (Sandbox Code Playgroud)$ gdb static (gdb) break natural_generator (gdb) run (gdb) disassemble Dump of assembler code for function natural_generator: push %rbp mov %rsp,%rbp movl $0x1,-0x4(%rbp) mov 0x177(%rip),%eax # (1) add $0x1,%eax mov %eax,0x16c(%rip) # (2) mov -0x4(%rbp),%eax add 0x163(%rip),%eax # 0x100001018 <natural_generator.b> pop %rbp retq End of assembler dump.
(行号的意见(1),(2) …
我试图了解小代码模型中使用的 RIP 相对偏移量。也许互联网上有关此主题的唯一可用资源是: https: //eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models 但在这篇文章中也有一些事情不清楚。我使用这个简单的程序来了解一些事情:
// sample.cc
int arr[10] = {0};
int arr_big[100000] = {0};
int arr2[500] = {0};
int main() {
int t = 0;
t += arr[7];
t +=arr_big[6];
t += arr2[10];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
汇编:g++ -c sample.cc -o sample.o
.text 部分的目标代码:( objdump -dS sample.o)
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
b: 8b 05 00 …Run Code Online (Sandbox Code Playgroud) 我有一个内存位置,其中包含一个我想要与另一个角色进行比较的角色(并且它不在堆栈的顶部,所以我不能只是pop它).如何引用内存位置的内容以便进行比较?
基本上我如何在语法上做到这一点.
I have tried to compile c code to assembly code using gcc -S -fasm foo.c.
The c code declare global variable and variable in the main function as shown below:
int y=6;
int main()
{
int x=4;
x=x+y;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
now I looked in the assembly code that has been generated from this C code and I saw, that the global variable y is stored using the value of the rip instruction pointer.
I thought that only const …
我有一个适用于Mac OS X的程序集hello world程序,如下所示:
global _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msg]
mov rdx, msg.len
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "Hello, World!", 10
.len: equ $ - msg
Run Code Online (Sandbox Code Playgroud)
我想知道这条线lea rsi, [rel msg]。为什么NASM强迫我这样做?据我了解,它msg只是指向可执行文件中某些数据的指针,这样做mov rsi, msg会将地址放入rsi。但是,如果我将替换为lea rsi, [rel msg],则NASM会引发此错误(注意:我使用的是命令nasm -f macho64 hello.asm):
hello.asm:9: fatal: No section for index 2 offset 0 found
Run Code Online (Sandbox Code Playgroud)
为什么会这样?有什么特别之处lea是mov …
GCC和Clang编译器似乎采用了一些黑暗魔法.该C代码只是否定了双重的价值,但汇编指令涉及逐位XOR和指令指针.有人可以解释发生了什么,为什么它是一个最佳解决方案.谢谢.
test.c的内容:
void function(double *a, double *b) {
*a = -(*b); // This line.
}
Run Code Online (Sandbox Code Playgroud)
生成的汇编程序指令:
(gcc)
0000000000000000 <function>:
0: f2 0f 10 06 movsd xmm0,QWORD PTR [rsi]
4: 66 0f 57 05 00 00 00 xorpd xmm0,XMMWORD PTR [rip+0x0] # c <function+0xc>
b: 00
c: f2 0f 11 07 movsd QWORD PTR [rdi],xmm0
10: c3 ret
Run Code Online (Sandbox Code Playgroud)
(clang)
0000000000000000 <function>:
0: f2 0f 10 06 movsd xmm0,QWORD PTR [rsi]
4: 0f 57 05 00 00 …Run Code Online (Sandbox Code Playgroud)