Search code examples
assemblynasm

How can 1 byte hold more than one value?


I'm making a simple assembly program, and I don't understand how, after reserving only 1 byte for a variable boxresult resb 1d, a "yes" or "no" can be stored in it, wouldn't I need at least 3 bytes ("no"+terminator) for it?

I've recently searched about it, and it doesn't seem to make sense to me, since: Question 1 says that by creating a initialized variable "db" it would reserve a byte for each char (which I understand), but in Question 2, creating a uninitialized variable how I did would only reserve 1 byte, which wouldn't be able to store more than 1 value (char), but it does. Here's my code:

;https://learn.microsoft.com/pt-br/windows/win32/api
;nasm -fwin32 main2.asm &&gcc main2.obj &&a.exe
;direct version

STD_OUTPUT_HANDLE EQU -11
STD_INPUT_HANDLE EQU -10
IDYES EQU 6
IDNO EQU 7

extern _MessageBoxA@16 ;4 parameters, each parameter occupies 4 bytes
extern _GetStdHandle@4 ; 1 parameter to identify output port
extern _WriteFile@20 ;5 parameters
extern _ExitProcess@4 ; 1 parameter for exit code

global _main

section .data ;initialized variables
    boxstring db "Choose", 0h ;ends with null
    yes db "yes", 0h
    no db "no", 0h

section .bss ;uninitialized variables
    StandardOutputHandler resd 1d ; 1 uninitialized double variable
    StandardInputHandler resd 1d
    written resd 1d
    boxresult resb 1d

section .text
    _main: ;function start
        ;all values indicated by the API (as far as I've seen) are in hexadecimal, in assembly, just need to declare the type at the end of the number, for example h for hexadecimal, d for decimal, etc.
        ;0 = null
        ;add values for combinations, example: 34h: 4=yesno+30=warning. That is, yes and no and warning icon
        push 44h
        push 0h
        push boxstring
        push 0h
        call _MessageBoxA@16
        cmp eax, IDYES
        jne else
        mov eax, [yes]
        jmp endif
        else:
            mov eax, [no]
        endif:
        mov [boxresult], eax
        push STD_OUTPUT_HANDLE ;output initialization
        call _GetStdHandle@4
        mov dword [StandardOutputHandler], eax
        push 0h
        push 0h
        push 3d
        push boxresult
        push dword [StandardOutputHandler]
        call _WriteFile@20

        push 0h
        call _ExitProcess@4

Solution

  • One byte can indeed only hold one byte. If you try to store more than one byte at the given address, by treating that address as the begin of a string, you'll overwrite memory that was not reserved.

    Assembly is even less forgiving of errors than C. If you reserve one byte and use two, that is your problem.