0

I just started out today with assembly, so I wanted to build a simple program which takes 2 numbers and prints their result.

Since I'm using mac, I have to assemble my code in 64 bits, so I assembled it using nasm -f macho64 -l calc.lst cal.asm, when I got the following errors:

calc.asm:25: error: Mach-O 64-bit format does not support 32-bit absolute addresses
calc.asm:33: error: Mach-O 64-bit format does not support 32-bit absolute addresses

enter code here

Here are lines 25 and 33:

[25] mov     rbx, [input]            ; Store the value of input
...
[33] add     rbx, [input]            ; Add the value of the latest input to the previous one

All I'm doing is referencing a pointer... I tried adding qword before the opening square bracket, but it changed nothing.

(and I know I am not doing the arithmetic correctly since I'm adding the ASCII values but I'll fix it later)

Here is the full code:

global start

section .data
    newline:    db  10
    input:      times 256 db  0
    .len:       equ $ - input

    prompt1:    db  'Enter a number: '
    .len:       equ $ - prompt1     ; The difference between the current working address and prompt1's address: the length of prompt1
    prompt2:    db  'Enter another number: '
    .len:       equ $ - prompt2
    resultmsg:  db  'The result is: '
    .len:       equ $ - resultmsg

section .text
start:
    mov     rsi, prompt1            ; Address of message
    mov     rdx, prompt1.len        ; Length of message
    call    print
    call    read
    call    print_newline

    mov     rbx, [input]            ; Store the value of input

    mov     rsi, prompt2
    mov     rdx, prompt2.len
    call    print
    call    read
    call    print_newline

    add     rbx, [input]            ; Add the value of the latest input to the previous one

    mov     rsi, resultmsg
    mov     rdx, resultmsg.len
    call    print

    push    rbx                     ; Push the sum in order to get a pointer to it (in rsp)
    mov     rsi, rsp
    mov     rdx, 8
    call    print
    call    print_newline

    call    exit



print:
    mov     rax, 0x2000004          ; Set command to write string
    mov     rdi, 1                  ; Set output to STDOUT
    syscall                         ; Call kernel
    ret

print_newline:
    mov     rsi, newline
    mov     rdx, 1
    call    print
    ret

read:
    mov     rax, 0x2000003          ; Set command to read string
    mov     rdi, 0                  ; Set input to STDIN
    mov     rsi, input
    mov     rdx, input.len
    syscall
    ret

exit:
    mov     rax, 0x2000001          ; Set command to exit
    mov     rdi, 0                  ; Set exit code to 0 (normal execution)
    syscall
Hexa
  • 3
  • 4
  • 2
    Try using `default rel` at the start of your program. – Ross Ridge Oct 12 '16 at 00:25
  • It works! What does that "deafult rel" do exactly? I would still like to know the exact cause of this problem – Hexa Oct 12 '16 at 00:28
  • It makes registerless memory references like that RIP-relative, as if the `REL` modified was used, so instead of 32-bit absolute address you get a 32-bit relative address. For the same reason you might want (or need to) use `lea rsi, [prompt1]` instead of `mov rsi, prompt1`, although the assembler maybe doing that already for you. – Ross Ridge Oct 12 '16 at 00:34
  • Thanks! By the way, is there any way to read a number from STDIN instead of an ASCII string? – Hexa Oct 12 '16 at 00:36
  • You have to do the conversion yourself or use a C function like `scanf`. – Ross Ridge Oct 12 '16 at 00:38
  • I did just now using `sub , '0'`. And one last thing, do you have any idea why when it prints the sum it prints absolutely nothing? – Hexa Oct 12 '16 at 00:40
  • 2
    Single-step through your code in a debugger and look at registers / memory before the `print` call to see what you're printing. Or use `strace` to trace the system calls. – Peter Cordes Oct 12 '16 at 05:53
  • @Hexa maybe you print the sum as actual value? It's the same case as with input, you have to convert number value into (ASCII?) string first, then call print. Or use clib's `printf` or similar.. (still "debugger" is absolute answer here) – Ped7g Oct 12 '16 at 09:41

0 Answers0