Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8229209
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T16:43:24+00:00 2026-06-07T16:43:24+00:00

Im learning to code in x86 assembly (32-bit at the moment) and I’m struggling

  • 0

I”m learning to code in x86 assembly (32-bit at the moment) and I’m struggling to understand the memory model completely. Particularly confusing is the semantics for labels, and the LEA instruction, and the layout of the executable. I wrote this sample program so i could inspect it running in gdb.

; mem.s
SECTION .data
    msg: db "labeled string\n"
    db "unlabeled-string\n"
    nls: db 10,10,10,10,10,10,10,10
SECTION .text
global  _start
_start:
    ; inspect msg label, LEA instruction
    mov eax, msg
    mov eax, &msg
    mov eax, [msg]
    ; lea eax, msg (invalid instruction)
    lea eax, &msg
    lea eax, [msg]

    ; populate array in BSS section
    mov [arr], DWORD 1
    mov [arr+4], DWORD 2
    mov [arr+8], DWORD 3
    mov [arr+12], DWORD 4

    ; trying to print the unlabeled string
    mov eax, 4
    mov ebx, 1
    lea ecx, [msg+15]
    int 80H

    mov eax, 1      ; exit syscall
    mov ebx, 0      ; return value
    int 80H
SECTION .bss
    arr: resw 16

I’ve assembled and linked with:

nasm -f elf -g -F stabs mem.s
ld -m elf_i386 -o mem mem.o

GDB session:

(gdb) disas *_start
Dump of assembler code for function _start:
   0x08048080 <+0>: mov    $0x80490e4,%eax
   0x08048085 <+5>: mov    0x80490e4,%eax
   0x0804808a <+10>:    mov    0x80490e4,%eax
   0x0804808f <+15>:    lea    0x80490e4,%eax
   0x08048095 <+21>:    lea    0x80490e4,%eax
   0x0804809b <+27>:    movl   $0x1,0x8049110
   0x080480a5 <+37>:    movl   $0x2,0x8049114
   0x080480af <+47>:    movl   $0x3,0x8049118
   0x080480b9 <+57>:    movl   $0x4,0x804911c
   0x080480c3 <+67>:    mov    $0x4,%eax
   0x080480c8 <+72>:    mov    $0x1,%ebx
   0x080480cd <+77>:    lea    0x80490f3,%ecx
   0x080480d3 <+83>:    int    $0x80
   0x080480d5 <+85>:    mov    $0x1,%eax
   0x080480da <+90>:    mov    $0x0,%ebx
   0x080480df <+95>:    int    $0x80

inspecting “msg” value:

(gdb) b _start
Breakpoint 1 at 0x8048080
(gdb) run
Starting program: /home/jh/workspace/x86/mem_addr/mem
(gdb) p msg
# what does this value represent?
$1 = 1700946284
(gdb) p &msg
$2 = (<data variable, no debug info> *) 0x80490e4
# this is the address where "labeled string" is stored
(gdb) p *0x80490e4
# same value as above (eg: p msg)
$3 = 1700946284
(gdb) p *msg
Cannot access memory at address 0x6562616c
# NOTE: 0x6562616c is ASCII values of 'e','b','a','l'
# the first 4 bytes from msg: db "labeled string"... little-endian
(gdb) x msg
0x6562616c: Cannot access memory at address 0x6562616c
(gdb) x &msg
0x80490e4 <msg>:    0x6562616c
(gdb) x *msg
Cannot access memory at address 0x6562616c

Stepping through one instruction at a time:

(gdb) p $eax
$4 = 0
(gdb) stepi
0x08048085 in _start ()
(gdb) p $eax
$5 = 134516964
0x0804808a in _start ()
(gdb) p $eax
$6 = 1700946284
(gdb) stepi
0x0804808f in _start ()
(gdb) p $eax
$7 = 1700946284
(gdb) stepi
0x08048095 in _start ()
(gdb) p $eax
$8 = 134516964

The array was populated with the values 1,2,3,4 as expected:

# before program execution:
(gdb) x/16w &arr
0x8049104 <arr>:    0   0   0   0
0x8049114:  0   0   0   0
0x8049124:  0   0   0   0
0x8049134:  0   0   0   0
# after program execution
(gdb) x/16w &arr
0x8049104 <arr>:    1   2   3   4
0x8049114:  0   0   0   0
0x8049124:  0   0   0   0
0x8049134:  0   0   0   0

I don’t understand why printing a label in gdb results in those two values. Also, how can I print the unlabeled string.
Thanks in advance

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T16:43:26+00:00Added an answer on June 7, 2026 at 4:43 pm

    Its somewhat confusing because gdb doesn’t understand the concept of labels, really — its designed to debug a program written in higher-level language (C or C++, generally) and compiled by a compiler. So it tries to map what it sees in the binary to high-level language concepts — variables and types — based on its best guess as to what is going on (in the absence of debug info from the compiler that tells it what is going on).

    what nasm does

    To the assembler, a label is value that hasn’t been set yet — it actually gets its final value when the linker runs. Generally, labels are used to refer to addresses in sections of memory — the actual address will get defined when the linker lays out the final executable image. The assembler generates relocation records so that uses of the label can be set properly by the linker.

    So when the assembler sees

    mov eax, msg
    

    it knows that msg is a label corresponding to an address in the data segment, so it generates an instruction to load that address into eax. When it sees

    mov eax, [msg]
    

    it generates an instruction to load 32-bits (the size of register eax) from memory at address of msg. In both cases, there will be a relocation generated so that the linker can plug in the final address msg ends up with.

    (aside — I have no idea what & means to nasm — it doesn’t appear anywhere in the documentation I can see, so I’m suprised it doesn’t give an error. But it looks like it treats it as an alias for [])

    Now LEA is a funny instruction — it has basically the same format as a move from memory, but instead of reading memory, it stores the address it would have read from into the destination register. So

    lea eax, msg
    

    makes no sense — the source is the label (address) msg, which is a (link time) constant and is not in memory anywhere.

    lea eax, [msg]
    

    works, as the source is in memory, so it sticks the address of the source into eax. This is the same effect as mov eax, msg. Most commonly, you only see lea used with more complex addressing modes, so that you can leverage the x86 AGU to do useful work other than just computing addresses. Eg:

    lea eax, [ebx+4*ecx+32]
    

    which does a shift and two adds in the AGU and puts the result into eax rather than loading from that address.

    what gdb does

    In gdb, when you type p <expression> it tries to evaluate <expression> to the best of its understanding of what the C/C++ compiler means for that expression. So when you say

    (gdb) p msg
    

    it looks at msg and says “that looks like a variable, so lets get the current value of that variable and print that”. Now it knows that compilers like to put global variables into the .data segment, and that they create symbols for those variables with the same name as the varible. Since it sees msg in the symbol table as a symbol in the .data segment, it assumes that is what is going on, and fetches the memory at that symbol and prints it. Now it has no idea what TYPE that variable is (no debug info), so it guesses that it is a 32-bit int and prints it as that.

    So the output

    $1 = 1700946284
    

    is the first 4 bytes of msg, treated as an integer.

    For p &msg it understands you want to take the address of the variable msg, so it give the address from the symbol directly. When printing addresses, gdb prints the type information it has about those addresses, thus the “data variable, no debug info” that comes out with it.

    If you want, you can use a cast to specify the type of something to gdb, and it will use that type instead of what it has guessed:

    (gdb) p (char)msg
    $6 = 108 'l'
    (gdb) p (char [10])msg
    $7 = "labeled st"
    (gdb) p (char *)&msg
    $8 = 0x80490e4 "labeled string\\nunlabeled-string\\n\n\n\n\n\n\n\n\n" <Address 0x804910e out of bounds>
    

    Note in the latter case here, there’s no NUL terminator on the string, so it prints out the entire data segment…


    To print the unlabelled string with sys_write, you need to figure out the address
    and length of string, which you almost have. For completeness you should also check the return value:

        mov ebx, 1           ; fd 1 (stdout)
        lea ecx, [msg+15]    ; address
        mov edx, 17          ; length
    write_more:
        mov eax, 4           ; sys_write
        int 80H              ; write(1, &msg[15], 17)
        test eax, eax        ; check for error
        js error             ; error, eax = -ERRNO
        add ecx, eax
        sub edx, eax
        jg write_more        ; only part of the string was written
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've just begun learning some x86 assembly on win32, and I've used masm with
Currently I am in the midst of learning x86 assembly for fun, I'm love
Learning client side code of an existing site, would like to understand some activity
Hi sorry still learning here and slow to learning code arguments. Just wondering could
What is machine learning ? What does machine learning code do ? When we
I'm fairly new to coding in general, learning to code in rails, and feel
I am learning some COM code and the following code puzzled me. STDMETHODIMP _(ULONG)
I'm looking through some code for learning purposes. I'm working through this portion of
I'm a beginner to C programming. I'm trying to learning how to code a
I am learning about the conversion of source code to machine code via the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.