-1

I keep getting errors with this code. Im just trying to print any value that's stored in a variable.

Im very new to assembly!!!

Im using a NASM simulator online at codingground.com

section .text
global _start      
_start:            

section .data
var1 db 44

section .text 
mov ah, var1


mov edx, len    ;message length
mov ecx, msg    ;message to write
mov ebx, 1      ;file descriptor (stdout)
mov eax, 4      ;system call number (sys_write)
int 0x80        ;call kernel
mov eax, 1      ;system call number (sys_exit)
int 0x80        ;call kernel

section .data
msg db var1 ,0xa        ;our dear string
len equ $ - msg         ;length of our dear string

Error: $nasm -f elf *.asm; ld -m elf_i386 -s -o demo *.o main.o: In function _start': main.asm:(.text+0x1): relocation truncated to fit: R_386_8 against .data' main.o: In function msg': main.asm:(.data+0x1): relocation truncated to fit: R_386_8 against .data'

hb91
  • 1
  • 2
  • 2
    Questions about build errors in code always need to quote the error message as part of the [mcve]. I assume it's from trying to put the address of `var1` into an 8-bit register. IDK why you want to do that, or put the value there when you're going to overwrite EAX with the call number for `write` a few instructions later. And also trying to put the address into a byte in .data with `db var1`, I guess. – Peter Cordes May 05 '22 at 14:06
  • 1
    If you want to print a number in a register, see [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/a/46301894). But that's unrelated to the bug in your code, you're not doing anything that could even print the byte stored at `var1`, let alone an ASCII-decimal string representation of that number. – Peter Cordes May 05 '22 at 14:07
  • sorry I just added the error message in an edit – hb91 May 05 '22 at 14:26
  • Added [relocation truncated to fit r\_386\_8 against .bss'](https://stackoverflow.com/q/46928566) as another duplicate to cover the direct cause of the error message. – Peter Cordes May 05 '22 at 14:28
  • the printing section of the code came from some one else. what I was trying to do is replace the message that belongs in quotes with the name of the variable. I know that's not proper assembly language, but that's the part I wanted help with. also just picked a random general purpose register for the variable to be stored in. – hb91 May 05 '22 at 14:30
  • Trial and error by throwing code at the wall is not a great way to get a handle on the super basics of assembly. There are a lot of ways to get things wrong, and the error messages often won't correct conceptual misunderstandings (like that `mov ah, var1` isn't a load, or that `db var1` won't copy the byte *at* var1, and there's no way to do that assemble-time reference to already-assembled bytes. Use an `equ` to put the `44` there twice) – Peter Cordes May 05 '22 at 14:34
  • I'd recommend finding a tutorial. There are some links in https://stackoverflow.com/tags/x86/info - some of them are good I think. Or looking at compiler output is helpful, especially if you know C well enough to understand what a given piece of code does to memory, although the closest GCC/clang can get to NASM is their GAS `.intel_syntax` which still uses different directives. (But generally works pretty similarly). [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) – Peter Cordes May 05 '22 at 14:37
  • ok I changed it to EQU and now there are no error messages, but its not printing the value either. – hb91 May 05 '22 at 15:31
  • THANKS for the links, I will check them out – hb91 May 05 '22 at 15:32
  • BTW, you're going to need a way to single-step your code, and run it under `strace` to see what args you actually passed to system calls. codingground.com seems to be a domain for sale so IDK what you're actually using, but I'm not aware of an online NASM dev environment with a debugger. That's *essential* for asm, moreso than any other language. https://www.onlinegdb.com/ has an assembly option, but it's GAS not NASM syntax. It might work for 32-bit mode with `-m32 -no-pie` in the build args. – Peter Cordes May 05 '22 at 15:37
  • here's a link to what ive been using https://www.tutorialspoint.com/compile_assembly_online.php – hb91 May 05 '22 at 16:21
  • Yeah, I don't see any debugger facilities there, so that's unusable for anything except sharing working code that you've already debugged locally, with GDB or whatever. (See GDB tips at the bottom of https://stackoverflow.com/tags/x86/info for examples of what you can do with a debugger). Or once you already know asm well, you can sometimes write simple programs without needing a debugger, but if there are any showstopper bugs where the symptoms don't clue you in to exactly what the problem was, it's still worth the time to use a debugger instead of staring at the code. – Peter Cordes May 05 '22 at 16:31
  • ok I will check out this one : http://asmdebugger.com – hb91 May 05 '22 at 17:54
  • http://asmdebugger.com/ looks interesting, but it doesn't seem to be a real assembler. Just a toy project, I think, that only does registers, not memory. And no error messages if it won't assemble, just failure to start single-stepping. It choked on a 486 instruction like `bswap eax`, as well as on `mov ecx, [foo]` where `foo` was just a label in the code. A real debugger can do what it does, but for real programs that use memory and system calls as well as registers. – Peter Cordes May 05 '22 at 18:15
  • do you have any recommendations? id rather use an online version rather than downloading programs. – hb91 May 05 '22 at 18:26
  • Like I said, I'm not aware of any usable online-debugger site with NASM. The closest I know of is https://www.onlinegdb.com/ with GAS syntax, but still can I think write 32-bit code for Linux. I already use Linux on my desktop all the time for decades, and already wanted GDB installed anyway, so the only reason I'd care about an online version would be to recommend to someone else. Last time I searched for an online NASM + debugger site (maybe a year ago?), I didn't fine one. – Peter Cordes May 05 '22 at 18:56
  • I changed "mov ah, var1" TO: "lea 0x36, var1" ...now it says "invalid combination of opcode and operands" for that line – hb91 May 05 '22 at 21:30
  • just wondering if you have any insight on my last comment. I am also trying to find a better debugger... – hb91 May 05 '22 at 22:13
  • actually just tried another debugger and it reads the same error message as what I said two comments above this one ^^ – hb91 May 05 '22 at 22:24
  • `lea` requires a register destination. IDK what you even wanted that instruction to do with an immediate destination; that's like C `0x36 = &var1` which makes zero sense. You can't assign to a numeric constant. `mov ecx, var1` would put the address of var1 in ECX, or `lea ecx, [var1]` would do the same thing less efficiently. – Peter Cordes May 06 '22 at 03:46
  • it seems to be reading that part. no more error messages, its just not printing Var1 because it wants a message in quotations. it is printing the comma after var1 there ...so ill have to find another way. I really was just guessing with that part...my guess was to copy what I would do in C++, which is to leave the quotes out, thus printing what's inside the variable. I know that's a terrible way to guess, but I already have this working bit of code for the text output/print part and I didnt want to change it. I think its looking like I might have to. – hb91 May 06 '22 at 14:35
  • You need ASCII digits in memory, and to pass a pointer to them to a `write` system call. As in [Add 2 numbers and print the result using Assembly x86](https://stackoverflow.com/a/28524951) which prints a number in EAX. So load your number into EAX (with `movzx eax, byte [var1]`) and use that code. You do eventually need to use the same `write` system call that you're using for a fixed-length constant string, but you shouldn't hard-code the length. That's what the linked duplicates are about; see the top of the page. – Peter Cordes May 06 '22 at 14:39
  • I'm assuming you're trying to learn how to write code that can print a runtime variable, not something that can *only* work on a compile-time-constant number. If that was what you wanted, I think NASM macros might be able to stringify an `equ` constant or a `%define` macro into a decimal string, to get something equivalent to `msg: db "44", 0xa`. (This is assembly language, not C++; nothing automatically behaves differently depending on types. Print-string code will at best output raw binary bytes, not start converting bytes to a decimal string representing the value if it didn't before) – Peter Cordes May 06 '22 at 14:40

0 Answers0