相关疑难解决方法(0)

gcc/clang如何假设字符串常量的地址是32位?

如果我编译这个程序:

#include <stdio.h>

int main(int argc, char** argv) {
    printf("hello world!\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于x86-64,asm输出使用movl $.LC0, %edi/ call puts.(请参阅godbolt上的完整asm输出/编译选项.)

我的问题是:GCC如何知道字符串的地址可以适合32位立即数操作数?为什么不需要使用movabs $.LC0, %rdi(即a mov r64, imm64,不是零或符号扩展imm32).

AFAIK,没有任何迹象表明加载器必须决定在任何特定地址加载数据部分.如果字符串存储在上面的某个地址,1ULL << 32那么movl将忽略更高的位.我对clang有类似的行为,所以我不认为这是GCC独有的.


我关心的原因是我想创建自己的数据段,它存在于我选择的任意地址(可能超过2 ^ 32)的内存中.

c linux linker x86-64 elf

5
推荐指数
1
解决办法
303
查看次数

重定位 R_X86_64_32S 针对 `.data' 不能在创建共享对象时使用;用 -fPIC 和 gcc 重新编译

当我使用 gcc 编译 print.s 时,出现以下错误:

/usr/bin/ld: /tmp/cc45uyZj.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)
  1. 我在另一个 linux 发行版中尝试了同样的方法,它运行得很好。

  2. 添加-fPIC没有帮助。apt-get 更新也不行。

  3. 如果你想看代码:https : //github.com/NEGU93/Compilation.git里面的练习 > Part1。当然是文件print.s(顺便说一句。当我做gcc时,所有的.s文件都有类似的错误)。

我想 Kali 发行版中缺少某些东西,但我不知道它可能是什么。

gcc

5
推荐指数
1
解决办法
6434
查看次数

Mach-O 64位格式不支持32位绝对地址。NASM访问阵列

使用以下命令在我的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)

x86-64 mach-o nasm

5
推荐指数
1
解决办法
1259
查看次数

由于从越界内存跳过cmov,很难调试SEGV

我正在尝试将一些高性能的汇编函数编写为练习,并且遇到了在运行程序时发生的奇怪的段错误,但在valgrind或nemiver中却没有.

基本上一个不应该运行的cmov,带有一个越界的地址,即使条件总是假的,也会让我发生段错误

我有一个快速和慢速的版本.缓慢的一直在工作.快速的一个工作,除非它收到一个非ascii字符,此时它崩溃可怕,除非我在adb或nemiver上运行.

ascii_flags只是一个128字节的数组(最后有一点空间),包含所有ASCII字符(alpha,numeric,printable等)的标志

这工作:

ft_isprint:
    xor EAX, EAX                ; empty EAX
    test EDI, ~127              ; check for non-ascii (>127) input
    jnz .error
    mov EAX, [rel ascii_flags + EDI]    ; load ascii table if input fits
    and EAX, 0b00001000         ; get specific bit
.error:
    ret
Run Code Online (Sandbox Code Playgroud)

但这不是:

ft_isprint:
    xor EAX, EAX                ; empty EAX
    test EDI, ~127              ; check for non-ascii (>127) input
    cmovz EAX, [rel ascii_flags + EDI]  ; load ascii table if input fits
    and EAX, flag_print         ; get …
Run Code Online (Sandbox Code Playgroud)

assembly gdb x86-64

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

使用Intel语法从寄存器名称中消除标签歧义

我想知道如何在Intel语法的某些指令中将标签名称与寄存器名称区分开。例如,call rdx通常意味着间接跳转,但是如果我们rdx在同一程序集文件中有标签怎么办?我认为可以将其解释为直接跳转到rdx。是否有任何符号告诉汇编器是哪个?

x86 assembly symbols gnu-assembler intel-syntax

5
推荐指数
1
解决办法
97
查看次数

GCC 程序集 x86 重定位警告:在 PIE 中创建 DT_TEXTREL

我正在用 AT&T 语法使用 Assembly x86(32 位)为大学编写一个项目。在课程中,我们使用 gnu Gas 和命令 ld 编译了源文件。现在我正在使用 GCC,因为我想创建一个汇编函数并从 C 程序调用它。

但是当我开始使用 GCC 进行编译时,我收到了这些关于链接和重定位的奇怪警告。

/usr/bin/ld: obj/telemetry.o: warning: relocation in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
Run Code Online (Sandbox Code Playgroud)

这是导致警告的文件的一个小示例。仅当我尝试访问/使用 .data 中声明的静态变量时才会发生警告

.file "telemetry.s"

.data 
test: .string "Example"
 
.text
.globl telemetry
.type telemetry, @function
telemetry:
    pushl %ebp
    movl %esp, %ebp
    pushl %ebx

    leal test, %ebx # if i comment this line warnings wont happen

    popl %ebx
    popl %ebp
    ret
Run Code Online (Sandbox Code Playgroud)

我仅在 Ubuntu 22.04.01 上使用当前使用的 gcc 版本 (11.2.0) 时收到警告。这是命令: …

c x86 assembly linker gcc

5
推荐指数
0
解决办法
1万
查看次数

小代码模型中相对偏移的计算

我试图了解小代码模型中使用的 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)

c++ assembly x86-64 abi relocation

5
推荐指数
1
解决办法
138
查看次数

"mov offset(%rip),%rax"是做什么的?

是否rax得到偏移加上该指令的地址,或下一个?从微码的角度来看,如果答案是下一条指令可能会更容易.

x86 assembly att

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

在不是地址/指针的值上使用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
查看次数

标签 统计

assembly ×7

x86 ×4

x86-64 ×4

c ×3

linker ×3

gcc ×2

abi ×1

att ×1

c++ ×1

elf ×1

gdb ×1

gnu-assembler ×1

intel-syntax ×1

linux ×1

mach-o ×1

memory-address ×1

nasm ×1

relocation ×1

symbols ×1