Basic use of immediates vs. square brackets in YASM/NASM x86 assembly
assembly, memory-address, nasm, x86, yasm
Solution
Indeed, your thought is correct.That is, bl will contain 5 and cl the memory address of buffer(in fact the label buffer is a memory address itself).
Now, let me explain the differences between the operations you mentioned:
moving an immediate into a register can be done using `mov reg,imm`.What may be confusing is that labels e.g buffer are immediate values themselves that contain an address.
You cannot really move a register into an immediate, since immediate values are constants, like `2` or `FF1Ah`.What you can do is move a register to the place where the constant points to.You can do it like `mov [const], reg` .
You can also use indirect addressing like `mov reg2,[reg1]` provided reg1 points to a valid location, and it will transfer the value pointed by reg1 to reg2.
So, `mov cl, buffer` will move the address of buffer to cl(which may or may not give the correct address, since cl is only one byte long) , whereas `mov cl, [buffer]` will get the actual value.
Summary
- When you use [a], then you refer to the value at the place where a points to.For example, if a is `F5B1`, then [a] refers to the address F5B1 in RAM.
- Labels are addresses,i.e values like `F5B1`.
- Values stored in registers do not have to be referenced to as [reg] because registers do not have addresses.In fact, registers can be thought of as immediate values.
Problem
Suppose I have the following declared: ``` section .bss buffer resb 1 ``` And these instructions follow in `section .text`: ``` mov al, 5 ; mov-immediate mov [buffer], al ; store mov bl, [buffer] ; load mov cl, buffer ; mov-immediate? ``` Am I correct in understanding that bl will contain the value 5, and cl will contain the memory address of the variable `buffer`? I am confused about the differences between - moving an immediate into a register, - moving a register into an immediate (what goes in, the data or the address?) and - moving an immediate into a register without the brackets - For example, `mov cl, buffer` vs `mov cl, [buffer]` UPDATE: After reading the responses, I suppose the following summary is accurate: - `mov edi, array` puts the memory address of the zeroth array index in `edi`. i.e. the label address. - `mov byte [edi], 3` puts the VALUE 3 into the zeroth index of the array - after `add edi, 3`, `edi` now contains the memory address of the 3rd index of the array - `mov al, [array]` loads the DATA at the zeroth index into `al`. - `mov al, [array+3]` loads the DATA at the third index into `al`. - `mov [al], [array]` is invalid because x86 can't encode 2 explicit memory operands, and because `al` is only 8 bits and can't be used even in a 16-bit addressing mode. Referencing the contents of a memory location. (x86 addressing modes) - `mov array, 3` is invalid, because you can't say "Hey, I don't like the offset at which `array` is stored, so I'll call it 3". An immediate can only be a source operand. - `mov byte [array], 3` puts the value 3 into the zeroth index (first byte) of the array. The `byte` specifier is needed to avoid ambiguity between byte/word/dword for instructions with memory, immediate operands. That would be an assemble-time error (ambiguous operand size) otherwise. Please mention if any of these is false. (editor's note: I fixed syntax errors / ambiguities so the valid ones actually are valid NASM syntax. And linked other Q&As for details)