0

I am trying to convert a C code (which reads number from stdin and compute the Fibonacci value of a number but the content of the code is no so important for the problem) to a nasm code using this Link: https://stackoverflow.com/a/20743090/9557460 but at step 3 when I put the command

nasm -f elf64 main.asm

I get

 main.asm:45: error: symbol `?_001' undefined
 main.asm:106: error: symbol `?_001' undefined

for some reason ?_001 is not defined but it is used in the code. and when removing it manually the code doesnt work.

The C code:

#include <stdio.h>
#include <stdlib.h>
#define MAX_PHYSICAL_MEMORY 500
static long M[MAX_PHYSICAL_MEMORY] = {
};
int main()
{
    for (int i=0; i<MAX_PHYSICAL_MEMORY; i++){//taking the numbers from         an array
        scanf("%ld", &M[i]);
    }

    int i = 0;
    //char *format;
    while (M[i] || M[i + 1] || M[i + 2]){//this is the sic program
        if ((M[M[i]] -= M[M[i + 1]]) < 0) 
            i = M[i + 2];
        else 
            i += 3;
    }
    for (i = 0; i < MAX_PHYSICAL_MEMORY; ++i) {//it is just do the printing
        printf("%ld ", M[i]);
    }
    printf("\n");

    return 0;
 } 

the NASM code generated :

       ; Disassembly of file: main.o
; Tue May 22 11:34:20 2018
; Mode: 64 bits
; Syntax: YASM/NASM
; Instruction set: Pentium Pro, x64

default rel

global main

extern putchar                                          ; near
extern __printf_chk                                     ; near
extern __isoc99_scanf                                   ; near


SECTION .text                           ; section number 1, code


SECTION .data                       ; section number 2, data


SECTION .bss                         ; section number 3, bss

M:                                                      ; byte
        resq    500                                     ; 0000


SECTION .rodata.str1.1                ; section number 4, const

?_002:                                                  ; byte
        db 25H, 6CH, 64H, 00H                           ; 0000 _ %ld.

?_003:                                                  ; byte
        db 25H, 6CH, 64H, 20H, 00H                      ; 0004 _ %ld .


SECTION .text.unlikely                   ; section number 5, code


SECTION .text.startup                   ; section number 6, code

main:   ; Function begin
        push    r12                                     ; 0000 _ 41: 54
        push    rbp                                     ; 0002 _ 55
        mov     r12d, ?_001                             ; 0003 _ 41: BC, 00000000(d)
        push    rbx                                     ; 0009 _ 53
        mov     ebx, M                                  ; 000A _ BB, 00000000(d)
        mov     rbp, rbx                                ; 000F _ 48: 89. DD
; Filling space: 6H
; Filler type: Multi-byte NOP
;       db 66H, 0FH, 1FH, 44H, 00H, 00H

ALIGN   8
?_004:  mov     rsi, rbp                                ; 0018 _ 48: 89. EE
        xor     eax, eax                                ; 001B _ 31. C0
        mov     edi, ?_002                              ; 001D _ BF, 00000000(d)
        add     rbp, 8                                  ; 0022 _ 48: 83. C5, 08
        call    __isoc99_scanf                          ; 0026 _ E8, 00000000(rel)
        cmp     r12, rbp                                ; 002B _ 49: 39. EC
        jnz     ?_004                                   ; 002E _ 75, E8
        xor     eax, eax                                ; 0030 _ 31. C0
; Filling space: 6H
; Filler type: Multi-byte NOP
;       db 66H, 0FH, 1FH, 44H, 00H, 00H

ALIGN   8
?_005:  movsxd  rdx, eax                                ; 0038 _ 48: 63. D0
; Note: Address is not rip-relative
        mov     rcx, qword [abs M+rdx*8]                ; 003B _ 48: 8B. 0C D5, 00000000(d)
        lea     edx, [rax+1H]                           ; 0043 _ 8D. 50, 01
        movsxd  rdx, edx                                ; 0046 _ 48: 63. D2
        test    rcx, rcx                                ; 0049 _ 48: 85. C9
; Note: Address is not rip-relative
        mov     rsi, qword [abs M+rdx*8]                ; 004C _ 48: 8B. 34 D5, 00000000(d)
        jnz     ?_006                                   ; 0054 _ 75, 16
        test    rsi, rsi                                ; 0056 _ 48: 85. F6
        jnz     ?_006                                   ; 0059 _ 75, 11
        lea     edx, [rax+2H]                           ; 005B _ 8D. 50, 02
        movsxd  rdx, edx                                ; 005E _ 48: 63. D2
; Note: Address is not rip-relative
        cmp     qword [abs M+rdx*8], 0                  ; 0061 _ 48: 83. 3C D5, 00000000(d), 00
        jz      ?_007                                   ; 006A _ 74, 24
?_006:
; Note: Address is not rip-relative
        mov     rdx, qword [abs M+rcx*8]                ; 006C _ 48: 8B. 14 CD, 00000000(d)
; Note: Address is not rip-relative
        sub     rdx, qword [abs M+rsi*8]                ; 0074 _ 48: 2B. 14 F5, 00000000(d)
        test    rdx, rdx                                ; 007C _ 48: 85. D2
; Note: Address is not rip-relative
        mov     qword [abs M+rcx*8], rdx                ; 007F _ 48: 89. 14 CD, 00000000(d)
        js      ?_008                                   ; 0087 _ 78, 3F
        add     eax, 3                                  ; 0089 _ 83. C0, 03
        jmp     ?_005                                   ; 008C _ EB, AA

; Filling space: 2H
; Filler type: NOP with prefixes
;       db 66H, 90H

ALIGN   8
?_007:  mov     rdx, qword [rbx]                        ; 0090 _ 48: 8B. 13
        xor     eax, eax                                ; 0093 _ 31. C0
        mov     esi, ?_003                              ; 0095 _ BE, 00000000(d)
        mov     edi, 1                                  ; 009A _ BF, 00000001
        add     rbx, 8                                  ; 009F _ 48: 83. C3, 08
        call    __printf_chk                            ; 00A3 _ E8, 00000000(rel)
        cmp     rbx, ?_001                              ; 00A8 _ 48: 81. FB, 00000000(d)
        jnz     ?_007                                   ; 00AF _ 75, DF
        mov     edi, 10                                 ; 00B1 _ BF, 0000000A
        call    putchar                                 ; 00B6 _ E8, 00000000(rel)
        pop     rbx                                     ; 00BB _ 5B
        xor     eax, eax                                ; 00BC _ 31. C0
        pop     rbp                                     ; 00BE _ 5D
        pop     r12                                     ; 00BF _ 41: 5C
        ret                                             ; 00C1 _ C3

; Filling space: 6H
; Filler type: Multi-byte NOP
;       db 66H, 0FH, 1FH, 44H, 00H, 00H

ALIGN   8
?_008:  add     eax, 2                                  ; 00C8 _ 83. C0, 02
        cdqe                                            ; 00CB _ 48: 98
; Note: Address is not rip-relative
        mov     eax, dword [abs M+rax*8]                ; 00CD _ 8B. 04 C5, 00000000(d)
        jmp     ?_005                                   ; 00D4 _ E9, FFFFFF5F
; main End of function
  • 1
    You have C, so you can just use `gcc -O2 -S -Mintel` to get asm, instead of assembling+linking the compiler output and disassembling that. – Peter Cordes May 22 '18 at 09:02
  • `?_001` is probably a data label; a bit strange that objconv didn't include it, though. – Peter Cordes May 22 '18 at 09:05
  • BTW, `gcc -S` output is in GAS syntax, which is MASM-like. But use that to get the `.rodata` / `.data` / `.bss` sections with labels, which you can port to NASM syntax and use with the `objconv` disassembly. – Peter Cordes May 22 '18 at 09:16
  • @PeterCordes I tried to do what you said but did not succeed. can you try your suggestion and post it? – נירייב שמואל May 22 '18 at 09:47
  • From the gcc asm output (https://godbolt.org/g/r2kejB), `r12d` gets `M+4000` (the end of the array, and there's nothing after it; apparently `objconv` failed to put a label after it), so replace `?_001` with `M+4000`. Or optimize the `cmp r12, rbp` into `cmp ebp, M+4000`, because you already know the address fits in 32 bits. GCC is just missing that optimization. **Or just put a `?_001:` label after the `resq 500`.** – Peter Cordes May 22 '18 at 09:56
  • @PeterCordes why simple not to use label 1: mov rsi, rbp ?? – Tsakiroglou Fotis May 22 '18 at 11:04
  • @TsakiroglouFotis: use how? Nothing about your comment makes any sense. `?_001` is not the address of any code. – Peter Cordes May 22 '18 at 11:07
  • @PeterCordes sorry , I was just asking... – Tsakiroglou Fotis May 22 '18 at 11:09
  • @TsakiroglouFotis: but what were you even asking? Add new code with that label? Or add `?_001:` to the same location as `?_004`? The answer to why not is because `?_001:` is the label for `M+4000`, at the end of the `resq`. It's a loop over the array, like `do {} while(++p != endp);` – Peter Cordes May 22 '18 at 11:27
  • I asked why don't you change "?_001:" with a literal label i.e "label_something" and ofcourse change also "jnz Label_something"? – Tsakiroglou Fotis May 22 '18 at 11:34
  • 1
    @TsakiroglouFotis: because that wasn't the problem. Meaningful label names is something you'd *also* do if you were going to turn this into a hand-optimized function. Note from the error messages that `?_001` is used from two separate places. But yeah, the sensible thing would be to call it `M_end` or something. Note that we're talking about `?_001`, not `?_004`, which you could rename to `scanf_loop:` Renaming it to `label_1` would be pointless; label names that start with `?` are weird, but apparently NASM accepts them. – Peter Cordes May 22 '18 at 11:53
  • @PeterCordes . thank you.I 've done some assembly myself , but never tried to convert c code into assembly code before. – Tsakiroglou Fotis May 22 '18 at 11:55

0 Answers0