0

I am learning assembly on Linux (NASM) x64 machine (I don't have access to 32 or 16 bit machine), and I am trying to display number on screen (reverse of number according to code but that's a start).

Number is predefined in section .data -> num.

I am quite a newbie at assembly programming and due to the lack of material on x64 assembly (really, cant find much, and all I was able to find was quite confusing) I am unable to resolve the issue.

The issue is that the code compiles an links with no errors/warnings, but it just displays some spaces (not even newline). If I remove the call _newl code from _disprem, those spaces are also gone. There is not even segment fault or something.

By the way, algorithm to get the remainder (to get the digits in a number) is num - (num / 10) * 10

section .data
    num:        dq      102 ;my default number to get the reverse of (for now)
    nl:         db      0x0a
    nlsize:     equ     $-nl
    ten:        dq      10

section .bss
    rem:        resq        1
    remsize:    equ     $-rem

section .text
    global _start

_start:

    cmp qword [num], 0
        jng _exit       ;jump to _exit if num is not greater than 0
    mov rax, [num]      ;move the number to rax
    mov rbx, [num]      ;move the number to rbx as well so that i have original number in register to subtract and get the remainder
    mov rcx, [ten]      ;move 10 to rcx to be the divisor
    div rcx             ;divide number in rax by 10
    mov [num], rax      ;get the quotient to get the remaining number for quotient
    mul rcx             ;multiply number in rax by 10
    sub rbx, rax        ;subtract rbx - rax and store the value in rax (right?)
    mov [rem], rbx      ;get the remainder from rax. this must be done right after div (WHY??????????)
    call _disprem       ;call _disprem to display the remainder... call returns the flow back to the caller right?
    jmp _start          ;get to the loop again

_exit:
    mov rax, 60
    mov rdi, 0
    syscall

_newl:
    mov rax, 1
    mov rdi, 1
    mov rsi, nl
    mov rdx, nlsize
    syscall
    ret

_disprem:
    mov rax, 1
    mov rdi, 1
    add qword [rem], 0x0000000000000030 ;since the rem variable is quadword (64 bit)
    mov rsi, rem
    mov rdx, remsize
    syscall
    sub qword [rem], 0x0000000000000030 ;get me my original number back plz thanks
    call _newl
    ret
halfer
  • 19,824
  • 17
  • 99
  • 186
Electrux
  • 19
  • 6
  • 1
    Your `num` is just a word (16 bits) but you use it as 64 bits. Also, the sys_write expects a pointer. PS: learn to use a debugger. – Jester Jun 04 '16 at 20:01
  • *(I dont have access to 32 or 16 bit machine)*: That's fine, don't waste your time with the complications of 16bit until you have a solid grasp of "normal" asm. 64bit Linux can run 32bit binaries, though, unless you disabled 32bit system call support in your kernel. Anyway, as long as you still eventually learn what the stack is, and how it works, there's no reason not to learn 64bit asm, instead of messing around with crufty old 32bit calling conventions (args on the stack) right away. See http://stackoverflow.com/tags/x86/info for lots of good stuff. – Peter Cordes Jun 05 '16 at 01:13
  • @Jester i dont use a debugger because people on Net say you learn better and get a solid grasp on asm without debugger... and am i bound to use the quadwords since I am on 64 bit unless I use the sub divisions of registers? thanks for all the help though :)....... I checked in my code what you said... now it gives me infinite loop of newlines... >. – Electrux Jun 05 '16 at 02:58
  • @PeterCordes thanks a lot for that... since I am using 64 bit system, I thought why not just understand the latest tech... not that 16 or even 32 bit would be useful anyways :P. Thanks for the link too... It's got some great content. I also found x64 tag which seems promising :D – Electrux Jun 05 '16 at 03:01
  • 1
    @Electrux: "people on the net" are wrong, then. Many kinds of asm bugs will result in identical crashes, and it's really cumbersome to put "debug prints" in asm. You don't need a *fancy* debugger, but **you need a debugger**. I consider it absolutely essential for writing code in asm, unless you're lucky and it works the first time. Single-stepping in a debugger and watching how the registers change will give you a better understanding than just "ok this worked" / "hmm this didn't". Anyway, go look up what `dw` means. Hint: it's space for a 16bit word, and as usual, Jester is right. – Peter Cordes Jun 05 '16 at 03:15
  • ok then... @PeterCordes thanks :) I found GDB debugger so I will learn to use it as well... Thanks everyone for the help :) – Electrux Jun 05 '16 at 15:00
  • If you're writing code that makes system calls, you're also going to find `strace` is gold. Just run `strace /bin/true` to see what it does. – Peter Cordes Jun 05 '16 at 15:38
  • oh... ok I will look up to that... btw i started using gdb debugger... man I must say, its golden... platinum if u please... helps a lot... i found may quirks in my code and have fixed them... but still... infinite loop right now and for the second iteration of the loop, the num value is 10, but on division, the register rax gets corrupted leading to infinite loop, with no output except newlines... I updated the code. On a side note... I am really loving this language for now... it's so much fun :D – Electrux Jun 05 '16 at 18:31
  • won't let me edit the post above... anyways, it's not an infinite-show-nothing loop... it actually shows '7' after a ton of empty lines and then keeps showing 7 forever – Electrux Jun 05 '16 at 18:38
  • Just click the [edit] button under the post... Happy debugging :) And yeah, I really enjoy writing in asm. I've always liked writing efficient code, and in asm you can actually predict what the bottlenecks will be, and how many cycles per iteration a loop will take. (It's super-complicated, and sometimes there are bottlenecks that are really hard to explain, but it's often doable. See Agner Fog's microarch guides). Being able to read compiler output and see if it did a good job or not is nice. :) – Peter Cordes Jun 05 '16 at 22:49
  • ah... coool well I like to write low level code because I feel like I am one with the machine... By the way, any solution to the 'weird' problem? I don't know why is the rax register is getting corrupted on the second iteration at the time of division with 10 – Electrux Jun 06 '16 at 02:30

0 Answers0