简体   繁体   中英

Why do I get segmentation fault for this minimal assembly?

I am a beginner at amd64 x86_64 assembly.

I am trying to allocate a static region of memory and then use it.

I try to move a pointer to the memory into registers with

movq .end_data_stack(%rip),%rdx                                                                                                                                                          
movq .codata(%rip), %rcx

I then try use the memory with

movq    %rdx, (%rcx)

But I get segmentation fault:

(gdb) set disassemble-next-line on
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/sam/compiler/minimal 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000055555555514b in main ()
=> 0x000055555555514b <main+18>:        48 89 11        mov    %rdx,(%rcx)

My full assembly is only 38 lines:

.global main                                                                                                                                                                                 
a.codata:                                                                                                                                                                                    
.data                                                                                                                                                                                        
    .skip 40                                                                                                                                                                                 
data_stack:                                                                                                                                                                                  
.data                                                                                                                                                                                        
    .zero 400, 0                                                                                                                                                                             
a.end_data_stack:                                                                                                                                                                            
.data                                                                                                                                                                                        
.LC0:                                                                                                                                                                                        
    .string "It worked: %p\n"                                                                                                                                                                
    .text                                                                                                                                                                                    
    .globl  main                                                                                                                                                                             
    .type   main, @function                                                                                                                                                                  
                                                                                                                                                                                             
.text                                                                                                                                                                                        
main:                                                                                                                                                                                        
    movq a.end_data_stack(%rip),%rdx                                                                                                                                                         
    movq a.codata(%rip), %rcx                                                                                                                                                                
    pushq   %rbp                                                                                                                                                                             
    movq    %rsp, %rbp                                                                                                                                                                       
    leaq    .LC0(%rip), %rax                                                                                                                                                                 
    movq %rcx, %rsi                                                                                                                                                                          
    movq    %rax, %rdi                                                                                                                                                                       
    movl    $0, %eax                                                                                                                                                                         
    call    printf@PLT                                                                                                                                                                       
                                                                                                                                                                                             
    movq a.end_data_stack(%rip),%rdx                                                                                                                                                         
    movq    %rsp, %rbp                                                                                                                                                                       
    leaq    .LC0(%rip), %rax                                                                                                                                                                 
    movq %rdx, %rsi                                                                                                                                                                          
    movq    %rax, %rdi                                                                                                                                                                       
    movl    $0, %eax                                                                                                                                                                         
    call    printf@PLT                                                                                                                                                                       
                                                                                                                                                                                             
    movq    %rdx, (%rcx)                                                                                                                                                                     
    popq    %rbp                                                                                                                                                                             
    ret  

                                                                                                                                                                                
    

I built with

gcc -o minimal minimal.S
./minimal

The problem was partly:

  1. Using movq rather than leaq
  2. Labels in the wrong sections.
  3. printf might be clobbering register values.

The following works:

.global main
.data
a.codata:
.data
    .skip 40

data_stack:
.data
    .zero 400, 0
a.end_data_stack:
.data
.LC0:
        .string "It worked: %p\n"
        .text
        .globl  main
        .type   main, @function

.text
main:
    leaq a.end_data_stack(%rip),%rdx
        leaq a.codata(%rip), %rcx         
        pushq   %rbp
        movq    %rsp, %rbp
        leaq    .LC0(%rip), %rax
    movq %rcx, %rsi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf@PLT

    movq a.end_data_stack(%rip),%rdx
        movq    %rsp, %rbp
        leaq    .LC0(%rip), %rax
    movq %rdx, %rsi
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf@PLT

    leaq a.end_data_stack(%rip),%rdx
        leaq a.codata(%rip), %rcx         
        movq    %rdx, (%rcx)
        popq    %rbp
    ret

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM