NASM program Assembly Language [closed]

2019-06-14 20:39发布

问题:

Program : enter an integer in base 10 from 0 to 255 and will change the number into base n (where n is from 2 to 9).

I know how to convert from base 10 to 2. but not base 10 to any other base. Any links or example might be sufficient to get me started.

回答1:

In order to provide the translation to the original answer, and mindful about giving a man a fish and feeding him for a day, the following is the NASM translation. Note: this is 32-bit code as in original:

; build and link (32-bit on x86_64)
;
; nasm -f elf -o baseconvert_32.o baseconvert_32.asm
; ld -m elf_i386 -o baseconvert_32 baseconvert_32.o

section .data

    base10  db 255
    newbase db 7
    result times 8 db 0
    newline db 10

section .text
                global _start

        _start:
                mov     edi, result         ; offset in result string

                xor     ax, ax              ; zero/clear ax register
                mov     al, [base10]        ; at start, current remainder = whole value
                mov     bl, [newbase]

        loop:
                div     bl                  ; divide current remainder by new base
                mov     [edi], ah
                cmp     al, 0               ; is the quotient zero?
                je      printchar           ; if it is we are done
                xor     ah, ah
                inc     edi                 ; move offset in result string (note digits
                jmp     loop                ; of answer are stored in reverse order)

        printchar:
                add    byte [edi], 48       ; add ascii '0' to digit to get printable char
                mov     eax, 4              ; linux sys_write
                mov     ebx, 1              ; stdout
                mov     ecx, edi            ; point to current digit
                mov     edx, 1              ; number of chars to print
                int     0x80                ; syscall
                dec     edi                 ; point to next digit
                cmp     edi, result         ; are we past the final digit?
                jge     printchar           ; if not, keep printing to stdout

                ; print newline
                mov     eax, 4
                mov     ebx, 1
                mov     ecx, newline
                mov     edx, 1
                int     0x80

                xor     ebx, ebx            ; set zero exit code
                mov     eax, 1              ; set syscall number to __NR_exit 1 (0x1 hex)
                int     0x80                ; call kernel (syscall 32-bit)

output:

$ ./baseconvert_32
513


回答2:

Well it's not NASM, it's gas, but the following code works for me on Linux. Perhaps you or some friendly stackoverflower can translate it into NASM.

Compile on linux with gcc -nostdlib -g -o filename filename.s.

You can change 255 and 7 to the dividend and base you want.

If you aren't running Linux/Unix, the system calls are unlikely to work.

The algorithm is fairly straightforward.

.data

base10:
    .byte 255
newbase:
    .byte 7
result:
    .byte 0,0,0,0,0,0,0,0 # since dividend <=255 and divisor >=2
                          # 8 digits in the new base is enough
newline:
    .byte 10 

.text

.global _start
_start:

    movl $result, %edi  # offset in result string

    xorw %ax, %ax
    movb base10, %al    # at start, current remainder = whole value
    movb newbase, %bl   

loop:
    divb %bl            # divide current remainder by new base
    movb %ah, (%edi)
    cmpb $0, %al        # is the quotient zero?
    je printchar        # if it is we are done
    xorb %ah, %ah
    incl %edi           # move offset in result string (note 
    jmp loop            # digits of answer are stored in reverse
                        # order)

printchar:

    addl $48, (%edi)    # add ascii '0' to digit to get printable char
    movl $4, %eax       # linux sys_write
    movl $1, %ebx       # stdout
    movl %edi, %ecx     # point to current digit
    movl $1, %edx       # one char to print
    int $0x80           # syscall
    decl %edi           # point to next digit
    cmpl $result, %edi  # are we past the final digit?
    jge printchar       # if we aren't keep going

    # print a newline
    movl $4, %eax       
    movl $1, %ebx
    movl $newline, %ecx
    movl $1, %edx
    int $0x80

    # finish nicely
    movl $0, %ebx   
    movl $1, %eax
    int $0x80


标签: assembly nasm