What is the difference between section and label in assembly in NASM?

3.7k views Asked by At

I am currently studying assembly through NASM assembler and I get stuck in the difference between section and label. I understood that section .dat, .bss or .text are used as a standard to declaration or initialization of variables and as a linker hook such as main() in C. But also, labels are used to assign a section in the code. So what is the obscure truth behind this?

1

There are 1 answers

3
Frank Kotler On BEST ANSWER

Well, there's a nice Manual, you know. http://www.nasm.us if you haven't got it.

It matters which output format you're using - the -f switch. In general... section and segment are aliases, they do the same thing. They are not case sensitive, you can use SEGMENT if you want to. Most output formats (not -f obj) have "known names" - .text, .data, .bss (and a few more). These are case sensitive - section .TEXT may not do what you want. Typically, section .text is executable, but read-only. Attempting to write to it will cause a segmentation fault (or whatever Windows calls it - GPF?). section .data is for your initialized data - msg db "Hello World!", 0 or frooble_count dd 42. section .bss is for uninitialized data it only reserves space in memory - and is not included in the disk file. You can only use the "reserve" pseudo-instructions there - resb, resw, resd, etc. The parameter after it indicates how many bytes (etc.) you want to reserve. In -f bin output format there are no sections/segments (that's what makes it a "flat binary") - Nasm just makes .text first, moves .data after it, and .bss last - you can write 'em in any order you want.

Labels do NOT define a section! Nasm just translates them to numbers - the address where they occur in your code - and that's what appears in your executable. You can use a label as a variable name, or as a point in your code that you might want to call or jmp to. All the same to Nasm. Some assemblers "remember" the size you said a variable was, and will throw an error if you try to use it wrong. Nasm has amnesia - you can do mov [mybyte], eax without complaint. Sometimes this is useful, more often it's an error. A variable that's "too big" is generally not a problem - a variable that's "too small" can cause an error, which often doesn't show up until later. Tough to debug! A label may not start with a decimal digit (and a number must start with a decimal digit). A label that starts with a period (dot) is a local label. Its scope is from the last non-local label to the next non-local label. See the Friendly Manual for (much) more detail - this is just an intro.

The word "main" doesn't mean anything special to Nasm, but is known to C (if you're linking against C). Some compilers spell it main, some _main, some (OpenWatcom) even spell it main_. It is the entrypoint - where execution starts when control is passed to your program. It does not need to be the first thing in section .text - but should be in that section, and should be declared "global" to tell the linker about it. "_start" is the default entrypoint for Linux (etc.). Unlike "main" it is not called, so you can't ret from it. Another name can be used, but you'll need to tell ld about it (-e myentry). It too should be global.

That's enough for now. See the Manual, and come back if (Ha!) you have other questions.