相关疑难解决方法(0)

在不是地址/指针的值上使用LEA?

我试图了解地址计算指令的工作原理,尤其是leaq命令.然后当我看到leaq用于进行算术运算的例子时,我感到困惑.例如,以下C代码,

long m12(long x) {
return x*12;
}
Run Code Online (Sandbox Code Playgroud)

在组装中

leaq (%rdi, %rdi, 2), %rax
salq $2, $rax
Run Code Online (Sandbox Code Playgroud)

如果我的理解是正确的,那么leaq应该移动任何(%rdi, %rdi, 2)应该2*%rdi+%rdi评估的地址%rax.我感到困惑的是,因为值x存储%rdi在内,这只是内存地址,为什么%rdi乘以3然后左移这个内存地址 2等于x乘以12?是不是当我们%rdi用3时,我们跳到另一个没有值x的内存地址?

c x86 assembly memory-address

4
推荐指数
2
解决办法
4927
查看次数

如何创建不可重定位符号

如何使用最近的gcc(启用PIC)创建不可重定位的符号?我基本上想让以下C程序打印NULL:

#include <stdio.h>

extern int mem_;

int main(void) {
  printf("%p\n", &mem_);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我试过的是一个小的汇编文件:

    .data
    .globl  mem_
    .type mem_,@object
    .set mem_, 0
Run Code Online (Sandbox Code Playgroud)

但这会创建一个可重定位的符号,该符号在运行时不具有值0。

背景:我正在尝试运行一个旧程序,该程序使用此技巧直接从Fortran作为数组访问(分配)内存。由于该程序有“ 10”?LOC,重写所有内容是不可行的。

[编辑] GNU汇编器手册将“绝对部分”记录

绝对部分:该部分的地址0始终“重定位”到运行时地址0。如果要引用的地址在重定位时ld不得更改,则此方法很有用。从这个意义上讲,我们说绝对地址是“无法重定位”的:它们在重定位期间不会改变。

这可能是我在这里需要的(对吗?),但是我找不到启用此部分的方法。该.struct指令记录为切换到“绝对部分”;但是以下汇编程序也不起作用:

    .globl  mem_
    .struct 0
mem_:   
Run Code Online (Sandbox Code Playgroud)

符号出现在此情况下,*ABS*objdump

$ objdump -t memc

memc:     file format elf64-x86-64
[...]
0000000000000540 g     F .text  000000000000002b              _start
0000000000201030 g       .bss   0000000000000000              __bss_start
000000000000064a g     F .text  000000000000003c              main
0000000000000000 g       *ABS*  0000000000000000              mem_
[...]
Run Code Online (Sandbox Code Playgroud)

但它仍然被迁移。

assembly linker

4
推荐指数
1
解决办法
363
查看次数

如何从汇编调用 C 函数以及如何静态链接它?

我正在玩弄并试图了解计算机和程序的低级操作。为此,我正在尝试链接 Assembly 和 C。

我有2个程序文件:

“callee.c”中的一些C代码:

#include <unistd.h>

void my_c_func() {
  write(1, "Hello, World!\n", 14);
  return;
}
Run Code Online (Sandbox Code Playgroud)

我在“caller.asm”中还有一些 GAS x86_64 程序集:

.text

.globl my_entry_pt

my_entry_pt:
  # call my c function
  call my_c_func # this function has no parameters and no return data

  # make the 'exit' system call
  mov $60, %rax # set the syscall to the index of 'exit' (60)
  mov $0, %rdi # set the single parameter, the exit code to 0 for normal exit
  syscall
Run Code Online (Sandbox Code Playgroud)

我可以像这样构建和执行程序:

$ …
Run Code Online (Sandbox Code Playgroud)

c linux assembly gcc x86-64

4
推荐指数
1
解决办法
220
查看次数

GDB“地址”。这些是什么?

这应该是一个非常简单、非常快速的问题。这些是 CI 中编写的程序的前 3 行:

Dump of assembler code for function main:
   0x0804844d <+0>: push   ebp
   0x0804844e <+1>: mov    ebp,esp
   0x08048450 <+3>: and    esp,0xfffffff0
   ... ... ... ... ... ... ...
Run Code Online (Sandbox Code Playgroud)

什么是0x0804844d和?它不受 ASLR 的影响。它仍然是内存地址,还是文件的相对点?0x0804844e0x08048450

memory assembly gdb memory-management

3
推荐指数
1
解决办法
1247
查看次数

与GCC组装导致与.data有关的奇怪的重定位错误

这是一个以前没有发生过的问题.我很确信这可能是我的包装回购的一个问题(我最近重新安装了我的Arch系统,而这刚刚开始发生).

我在x86_64中写了一个小小的hello世界:

.data
str:    .asciz  "Test"

.text
.globl main
main:
    sub $8, %rsp
    mov $str, %rdi
    call puts
    add $8, %rsp
    ret
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用GCC进行汇编和链接 - 就像我过去做过很多次一样 - 简单地说:

gcc test.s -o test

然后输出此错误:

/ usr/bin/ld:/tmp/ccAKVV4D.o:在创建共享对象时,不能使用针对`.data'的重定位R_X86_64_32S; 使用-fPIC/usr/bin/ld重新编译:最终链接失败:输出collect2上的不可表示的部分:错误:ld返回1退出状态

这个错误从来没有发生在我身上.我试图通过谷歌搜索相同的错误消息解决问题,但它提出了具体的事情,而我认为这是一个普遍的问题.我已经尝试重新安装base-devel和整个GCC工具链.我不知道我还能做什么(请不要建议使用nasm,这是异端邪说).

我想我错过了一些明显的东西,但是我已经将GCC用于我的装配需求很长一段时间了.

assembly gcc gnu-assembler

3
推荐指数
1
解决办法
3235
查看次数

制作共享对象时不能使用针对 .data 的重定位 R_X86_64_32S(64 位 NASM + gcc)

我正在尝试使用 NASM 和 GCC 制作一个程序:

global main
extern puts

section .data
  hi db 'hello', 0

section .text
main:
  push hi
  call puts
  ret
Run Code Online (Sandbox Code Playgroud)

我正在构建:

nasm -f elf64 main.asm
gcc main.o -o main
rm main.o
Run Code Online (Sandbox Code Playgroud)

我得到:

/usr/bin/ld: main.o: relocation R_X86_64_32S against `.data' 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)

从像这样的示例中存在奇怪的堆栈操作来判断,我有一种感觉我做错了一些事情。不过,出于某种原因,我找不到任何实际解释这一点的文档(事实上,我几乎找不到任何使用 NASM 进行 64 位开发的有用文档,这使得我迄今为止所做的一切都成为真正的做起来很痛苦),并且添加类似的东西对我的错误输出没有任何影响。

更新:

我一直在看 …

c linux assembly libc nasm

3
推荐指数
1
解决办法
3792
查看次数

如何将数字转换为十六进制?

给定寄存器中的数字(二进制​​整数),如何将其转换为十六进制ASCII数字字符串?

数字可以存储在存储器中或即时打印,但存储在存储器中并一次打印通常更有效.(您可以修改存储的循环,而不是一次打印一个循环.)

我们能否有效地处理与SIMD并行的所有半字节?(SSE2或更高版本?)

x86 assembly hex simd avx512

3
推荐指数
1
解决办法
342
查看次数

GCC 上 x86 intel asm 中方括号前的偏移量

从我发现的所有文档中,没有提到像offset[var+offset2]Intel x86 语法那样的语法,但是 GCC 有以下标志

gcc -S hello.c -o - -masm=intel

对于这个程序

#include<stdio.h>
int main(){
    char c = 'h';
    putchar(c);
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

产生

    .file   "hello.c"
    .intel_syntax noprefix
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    sub rsp, 16
    mov BYTE PTR -1[rbp], 104
    movsx   eax, BYTE PTR -1[rbp]
    mov edi, eax
    call    putchar@PLT
    mov eax, 0
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc gnu-assembler intel-syntax

3
推荐指数
1
解决办法
243
查看次数

为什么在NASM中使用相对RIP寻址?

我有一个适用于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]。为什么NA​​SM强迫我这样做?据我了解,它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)

为什么会这样?有什么特别之处leamov …

assembly nasm cpu-registers memory-address mov

2
推荐指数
2
解决办法
3874
查看次数

在GNU中以.intel_syntax区分内存与常量

我有一条用Intel语法编写的指令(使用gas作为汇编程序),看起来像这样:

mov rdx, msg_size
...
msg: .ascii "Hello, world!\n"
     .set msg_size, . - msg
Run Code Online (Sandbox Code Playgroud)

但是该mov指令正在汇编到mov 0xe,%rdx,而不是mov $0xe,%rdx我期望的那样。我应该如何编写第一条指令(或的定义msg_size)以获得预期的行为?

assembly gnu-assembler intel-syntax

2
推荐指数
1
解决办法
518
查看次数