syntax to compile 16 bit (8086code) in nasm - nasm

I'm confused how to compile 8086 code in nasm.
i used following command to assemble:
nasm hello.asm -o hello.o //;(Something wrong with this?)
This is 8086 Hello world code:
USE16
.model small
.stack 100h
.data
msg db "Hello World !$"
.code
main proc near
mov ax,#data
mov ds,ax
mov dx, offset msg
mov ah, 09h
int 21h
mov ah,00
int 21h
endp
end main
And this is the output
nasm hello.asm -o hello.o
hello.asm:3: error: parser: instruction expected
hello.asm:4: error: parser: instruction expected
hello.asm:5: warning: label alone on a line without a colon might be in error [-w+label-orphan]
hello.asm:9: warning: label alone on a line without a colon might be in error [-w+label-orphan]
hello.asm:11: error: parser: instruction expected
hello.asm:16: error: comma, colon, decorator or end of line expected after operand
hello.asm:23: warning: label alone on a line without a colon might be in error [-w+label-orphan]
hello.asm:24: error: parser: instruction expected

Related

.data section annoying error with nasm [duplicate]

I wrote the following simple program, but nasm refuses to compile it.
section .text
global _start
_start:
mov rax, 0x01
mov rdi, 0x01
mov rsi, str
mov rdx, 0x03
syscall
mov rax, 60
syscall
segment .data
str db 'Some string'
nasm -f elf64 main.asm
main.asm:15: error: comma, colon, decorator or end of line expected after operand
As I read in this answer this is because str is an instruction mnemonic. So I added a colon to str and now it compiles fine. But what about the line
mov rsi, str
str is an instruction mnemonic here, but it still compiles fine. Why?
As the NASM manual explains, other than macro definitions and directives, the format of a NASM source line has some combination of these four fields:
label: instruction operands ; comment
After it sees mov as the mnemonic, it's no longer considering the remaining tokens as possible instruction mnemonics. Assembly language is strictly one instruction per statement.
If you wanted the bytes that encode an str ax instruction as the immediate operand for mov-sign-extended-imm32, you'd have to do that yourself with a numeric constant. NASM syntax doesn't have a way to do that for you, so its parser doesn't need to recurse into the operands once its found a mnemonic.
Or instead of encoding str manually, use a db to emit the bytes of the mov instruction.
db 0x48, 0xc7, 0xc6 ; REX.W prefix, opcode for mov r/m64,imm32, ModR/M = rsi destination
str [rax+1] ; a disp8 makes this 4 bytes long.
;; same machine code as
mov rsi, strict dword 0x0148000f ; str [rax+1]
;; nasm optimizes it to mov esi, imm32 without strict dword.
;; I guess I should have used that 5-byte instruction for the DB version...

Why does this NASM assembly program print nothing

I have the following assembly, which I assemble with NASM and then link with gcc:
section .text
extern printf
global main
main:
sub rsp, 8 ;align stack pointer
mov rax, 0 ;no vector arguments
mov rdi, intro_message ;First argument
call printf
mov rax, 60 ;exit
syscall
section .data
intro_message:
db 'Hello world',0
When I run ./a.out, nothing is printed, and the instruction pointer seems to have moved to an invalid location. What have I done wrong?

nasm "error: comma, colon, decorator or end of line expected after operand"

I'm on Debian 9. These are the errors:
andrea#debian:~/Assembly/sandbox$ nasm -f elf -g -F stabs sandbox.asm
sandbox.asm:8: error: comma, colon, decorator or end of line expected after operand
sandbox.asm:9: error: comma, colon, decorator or end of line expected after operand
sandbox.asm:11: error: comma, colon, decorator or end of line expected after operand
sandbox.asm:12: error: comma, colon, decorator or end of line expected after operand
This is the code:
section .data
section .text
global _start
_start:
nop
mov eax 10
mov ebx 12
mov eax 1
mov ebx 0
int 80H
nop
section .bss
What's the problem causing these errors and how can I fix it?
If I use the following code where I fix the commas between operands I get a different error:
section .data
section .text
global_start
_start:
nop
mov eax,10
mov ebx,12
mov eax,1
mov ebx,0
int 80H
nop
section .bss
The error I get is:
sandbox.asm:4: warning: label alone on a line without a colon might be in error
Why do I get this error and how can I fix it?
I suppose there is a space missing and it should be:
global _start
in line 4.
I also suspected that the hexadecimal constant may be in incorrect format, because of missing 0 prefix, but it should be ok as long as the number starts with a digit, as Michael Petch mentioned in the comments (and according to the documentation of NASM available here: http://www.nasm.us/doc/nasmdoc3.html).

Compiling in NASM simple program

I'm trying to compile this program using NASM:
.model small
.STACK 100h
.data
no dw 31429
nstr db 6 dup(' ')
idv dw 10
.code
.startup
mov ax, dgroup
mov ds, ax
mov si,5
mov nstr[si], '$'
dec si
mov ax, no
mov dx,0
loop1:
div idv
add dl, '0'
mov nstr[si],dl
dec si
mov dx,0
cmp ax,0
jne loop1
listn:
mov ah, 09h
mov dx, offset nstr
int 21h
stopprg:
mov ah, 4ch
int 21h
end
And here's the output:
Afis.asm:6: error: attempt to define a local label before any non-local labels
Afis.asm:6: error: parser: instruction expected
Afis.asm:7: error: attempt to define a local label before any non-local labels
Afis.asm:7: error: parser: instruction expected
Afis.asm:8: warning: label alone on a line without a colon might be in error
Afis.asm:8: error: attempt to define a local label before any non-local labels
Afis.asm:10: error: comma expected after operand 1
Afis.asm:12: warning: label alone on a line without a colon might be in error
Afis.asm:13: warning: label alone on a line without a colon might be in error
Afis.asm:20: error: comma, colon, decorator or end of line expected after operand
Afis.asm:37: error: comma, colon, decorator or end of line expected after operand
Afis.asm:49: error: comma, colon, decorator or end of line expected after operand
Afis.asm:55: warning: label alone on a line without a colon might be in error
From what I know the program works fine with DosBOX, as my colleague told me, unfortunately I'm using linux and I cannot understand why I'm getting those errors.
Can someone point out where I'm making errors and how I can fix this?

nasm,86_64,linux,"hello world" program. when link ,it says "relocation truncated to fit"

[section .data]
strHello db "Hello World"
STRLEN equ $-strHello
MessageLength equ 9
Message db "hi!!!! "
[section .text]
global main
main:
mov edx,STRLEN;
mov ecx,strHello;
mov ebx,1
mov eax,4
int 0x80
call DispStr
mov ebx,0
mov eax,1
int 0x80
DispStr:
mov ax,MessageLength
mov dh,0
mul dh
add ax,Message
mov bp,ax
mov ax,ds
mov es,ax
mov cx,MessageLength
mov ax,01301h
mov bx,0007h
mov dl,0
int 10h
ret
Compile and run:
$ nasm -f elf64 helloworld.asm -o helloworld.o
$ gcc -s -o helloworld helloworld.o
helloworld.o: In function `DispStr':
helloworld.asm:(.text+0x31): relocation truncated to fit: R_X86_64_16 against `.data'
collect2: ld return 1
This exact error happens because at:
add ax,Message
ax is only 16-bit wide, but Message is a 64-bit wide address, so it won't fit during relocation.
I have explained this error in detail at: https://stackoverflow.com/a/32639540/895245
The solution in this case is to use a linker script as mentioned at: Using .org directive with data in .data section: In connection with ld
This repository contains working examples of boot sectors and BIOS: https://github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0
Since you're in 64-bit mode, you won't be able to use BIOS functions (i.e. the int 10h instruction). Even if you could, BIOS uses a different addressing mechanism, so attempting to use the address of Message wouldn't work anyway.
Also, wouldn't the first 3 lines of the DispStr function zero out ax? (since you're multiplying by dh, which was just set to zero)

Resources