1
[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
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
DunkOnly
  • 1,682
  • 4
  • 17
  • 39
  • Since I can't test without nasm, I can only point you [here](http://www.technovelty.org/c/relocation-truncated-to-fit-wtf.html). – Joachim Isaksson Jun 26 '13 at 11:44
  • Looks like you're trying to add a 64-bit address (`Message`) to a 16-bit register (`AX`), which obviously isn't going to fit. You could try something like `add ax,(Message & 0xFFFF)`. Though it seems unlikely that using `int 10h/ah=13h` would work in 64-bit mode. – Michael Jun 26 '13 at 12:02
  • thank you Michael .but when compile it says : '&' operator may only be applied to scalar values – DunkOnly Jun 26 '13 at 12:10
  • Ok, the syntax might be slightly different. But like I said, trying to use a real mode interrupt in 64-bit mode (or even in 32-bit protected mode) is not going to work out-of-the-box. You could use something like libx86 if you really, _really_ need to use such an interrupt, but I doubt that. – Michael Jun 26 '13 at 12:18
  • thank you . I mean... which interrupt do you mean? – DunkOnly Jun 26 '13 at 12:26
  • The last one (`10h`). – Michael Jun 26 '13 at 12:28
  • by the way,may I ask you the difference between the two `int`? – DunkOnly Jun 26 '13 at 12:32
  • `int 10h` is 16-bit code. `int 80h` is 32-bit code... but will still work in 64-bit code, I'm told - you'd want to use the 32-bit sys_call numbers (4 for sys_write). . 64-bit code would use `syscall`. – Frank Kotler Jun 26 '13 at 16:53
  • does `syscall` equal to BIOS-call? or syscall is a kind of linux-call? – DunkOnly Jun 27 '13 at 01:55
  • `syscall` is an instruction. 64-bit Linux uses it to request kernel services... much as 32-bit Linux uses `int 80h`. – Frank Kotler Jun 27 '13 at 08:26
  • thank you Frank Kotler. So what is bios call ? – DunkOnly Jun 27 '13 at 13:29
  • BIOS interrupts (I guess that's what you mean?) are a series of interrupts providing services for screen, keyboard, disk, etc. They are 16-bit code, useful when the machine first boots, but once the CPU has been put in 32-bit protected mode or 64-bit "long mode" (done by your OS), they simply won't work. Can be emulated by "DosBox" if you insist on using them. I wouldn't. – Frank Kotler Jun 27 '13 at 17:03
  • @FrankKotler : That is true, but you can switch out of long mode or 32/16 bit protected mode to the other modes. On a multicore system you can in theory put one core into long mode and have another core run in real mode (Each core on a system once started will generally start in Real Mode) – Michael Petch Sep 21 '15 at 00:10
  • @MichaelPetch hi Michael - we still chewing this bone? I expect it would be amusing programming one core in one mode and one core in another, no? :) – Frank Kotler Sep 21 '15 at 04:08

2 Answers2

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

Community
  • 1
  • 1
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
0

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)

Drew McGowen
  • 11,471
  • 1
  • 31
  • 57
  • whatif `Message: db "hi!!!! "` ? in fact , in the code I copyed to here , the `dh` is used as switch(dh) – DunkOnly Jul 01 '13 at 14:19
  • by the way ,would you please take a look at this question? http://stackoverflow.com/questions/17406054/how-to-change-jmp-and-popfd-to-64-bit-code – DunkOnly Jul 01 '13 at 14:20