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 525795
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T08:42:33+00:00 2026-05-13T08:42:33+00:00

I’m trying to learn assembly using Dr Paul Carter’s pcasm book: http://www.drpaulcarter.com/pcasm/ The author

  • 0

I’m trying to learn assembly using Dr Paul Carter’s pcasm book: http://www.drpaulcarter.com/pcasm/

The author doesn’t packaged Mac OS X samples, then I’ve started using from linux sources. Here is the first sample, that uses his library asm_io.

I’m getting Segmentation Fault when running it. Why? What need to be changed to run in mac?

I think if you know asm, maybe you can tell me what’s happening.

Here’s the sources.

asm_io.asm:

;
; file: asm_io.asm
; Assembly I/O routines
; To assemble for DJGPP
;   nasm -f coff -d COFF_TYPE asm_io.asm
; To assemble for Borland C++ 5.x
;   nasm -f obj -d OBJ_TYPE asm_io.asm
; To assemble for Microsoft Visual Studio
;   nasm -f win32 -d COFF_TYPE asm_io.asm
; To assemble for Linux
;   nasm -f elf -d ELF_TYPE asm_io.asm
; To assemble for Watcom
;   nasm -f obj -d OBJ_TYPE -d WATCOM asm_io.asm
; IMPORTANT NOTES FOR WATCOM
;   The Watcom compiler's C library does not use the
;   standard C calling convention. For example, the
;   putchar() function gets its argument from the
;   the value of EAX, not the stack.


%define NL 10
%define CF_MASK 00000001h
%define PF_MASK 00000004h
%define AF_MASK 00000010h
%define ZF_MASK 00000040h
%define SF_MASK 00000080h
%define DF_MASK 00000400h
%define OF_MASK 00000800h


;
; Linux C doesn't put underscores on labels
;
%ifdef ELF_TYPE
  %define _scanf   scanf
  %define _printf  printf
  %define _getchar getchar
  %define _putchar putchar
%endif

;
; Watcom puts underscores at end of label
;
%ifdef WATCOM
  %define _scanf   scanf_
  %define _printf  printf_
  %define _getchar getchar_
  %define _putchar putchar_
%endif

%ifdef OBJ_TYPE
segment .data public align=4 class=data use32
%else
segment .data
%endif

int_format     db  "%i", 0
string_format       db  "%s", 0
reg_format     db  "Register Dump # %d", NL
      db  "EAX = %.8X EBX = %.8X ECX = %.8X EDX = %.8X", NL
                    db  "ESI = %.8X EDI = %.8X EBP = %.8X ESP = %.8X", NL
                    db  "EIP = %.8X FLAGS = %.4X %s %s %s %s %s %s %s", NL
             db  0
carry_flag     db  "CF", 0
zero_flag     db  "ZF", 0
sign_flag     db  "SF", 0
parity_flag     db "PF", 0
overflow_flag     db "OF", 0
dir_flag     db "DF", 0
aux_carry_flag     db "AF", 0
unset_flag     db "  ", 0
mem_format1         db  "Memory Dump # %d Address = %.8X", NL, 0
mem_format2         db  "%.8X ", 0
mem_format3         db  "%.2X ", 0
stack_format        db  "Stack Dump # %d", NL
             db  "EBP = %.8X ESP = %.8X", NL, 0
stack_line_format   db  "%+4d  %.8X  %.8X", NL, 0
math_format1        db  "Math Coprocessor Dump # %d Control Word = %.4X"
                    db  " Status Word = %.4X", NL, 0
valid_st_format     db  "ST%d: %.10g", NL, 0
invalid_st_format   db  "ST%d: Invalid ST", NL, 0
empty_st_format     db  "ST%d: Empty", NL, 0

;
; code is put in the _TEXT segment
;
%ifdef OBJ_TYPE
segment text public align=1 class=code use32
%else
segment .text
%endif
 global read_int, print_int, print_string, read_char
 global  print_char, print_nl, sub_dump_regs, sub_dump_mem
        global  sub_dump_math, sub_dump_stack
        extern  _scanf, _printf, _getchar, _putchar

read_int:
 enter 4,0
 pusha
 pushf

 lea eax, [ebp-4]
 push eax
 push dword int_format
 call _scanf
 pop ecx
 pop ecx

 popf
 popa
 mov eax, [ebp-4]
 leave
 ret

print_int:
 enter 0,0
 pusha
 pushf

 push eax
 push dword int_format
 call _printf
 pop ecx
 pop ecx

 popf
 popa
 leave
 ret

print_string:
 enter 0,0
 pusha
 pushf

 push eax
 push    dword string_format
 call _printf
 pop ecx
 pop ecx

 popf
 popa
 leave
 ret

read_char:
 enter 4,0
 pusha
 pushf

 call _getchar
 mov [ebp-4], eax

 popf
 popa
 mov eax, [ebp-4]
 leave
 ret

print_char:
 enter 0,0
 pusha
 pushf

%ifndef WATCOM
 push eax
%endif
 call _putchar
%ifndef WATCOM
 pop ecx
%endif

 popf
 popa
 leave
 ret


print_nl:
 enter 0,0
 pusha
 pushf

%ifdef WATCOM
 mov eax, 10  ; WATCOM doesn't use the stack here
%else
 push dword 10 ; 10 == ASCII code for \n
%endif
 call _putchar
%ifndef WATCOM
 pop ecx
%endif
 popf
 popa
 leave
 ret


sub_dump_regs:
 enter   4,0
 pusha
 pushf
 mov     eax, [esp]      ; read FLAGS back off stack
 mov [ebp-4], eax    ; save flags

;
; show which FLAGS are set
;
 test eax, CF_MASK
 jz cf_off
 mov eax, carry_flag
 jmp short push_cf
cf_off:
 mov eax, unset_flag
push_cf:
 push eax

 test dword [ebp-4], PF_MASK
 jz pf_off
 mov eax, parity_flag
 jmp short push_pf
pf_off:
 mov eax, unset_flag
push_pf:
 push eax

 test dword [ebp-4], AF_MASK
 jz af_off
 mov eax, aux_carry_flag
 jmp short push_af
af_off:
 mov eax, unset_flag
push_af:
 push eax

 test dword [ebp-4], ZF_MASK
 jz zf_off
 mov eax, zero_flag
 jmp short push_zf
zf_off:
 mov eax, unset_flag
push_zf:
 push eax

 test dword [ebp-4], SF_MASK
 jz sf_off
 mov eax, sign_flag
 jmp short push_sf
sf_off:
 mov eax, unset_flag
push_sf:
 push eax

 test dword [ebp-4], DF_MASK
 jz df_off
 mov eax, dir_flag
 jmp short push_df
df_off:
 mov eax, unset_flag
push_df:
 push eax

 test dword [ebp-4], OF_MASK
 jz of_off
 mov eax, overflow_flag
 jmp short push_of
of_off:
 mov eax, unset_flag
push_of:
 push eax

 push    dword [ebp-4]   ; FLAGS
 mov eax, [ebp+4]
 sub eax, 10         ; EIP on stack is 10 bytes ahead of orig
 push eax             ; EIP
 lea     eax, [ebp+12]
 push    eax             ; original ESP
 push    dword [ebp]     ; original EBP
        push    edi
        push    esi
 push    edx
 push ecx
 push ebx
 push dword [ebp-8]   ; original EAX
 push dword [ebp+8]   ; # of dump
 push dword reg_format
 call _printf
 add esp, 76
 popf
 popa
 leave
 ret     4

sub_dump_stack:
 enter   0,0
 pusha
 pushf

 lea     eax, [ebp+20]
 push    eax             ; original ESP
 push    dword [ebp]     ; original EBP
 push dword [ebp+8]   ; # of dump
 push dword stack_format
 call _printf
 add esp, 16

 mov ebx, [ebp] ; ebx = original ebp
 mov eax, [ebp+16]   ; eax = # dwords above ebp
 shl eax, 2          ; eax *= 4
 add ebx, eax ; ebx = & highest dword in stack to display
 mov edx, [ebp+16]
 mov ecx, edx
 add ecx, [ebp+12]
 inc ecx  ; ecx = # of dwords to display

stack_line_loop:
 push edx
 push ecx  ; save ecx & edx

 push dword [ebx] ; value on stack
 push ebx  ; address of value on stack
 mov eax, edx
 sal eax, 2  ; eax = 4*edx
 push eax  ; offset from ebp
 push dword stack_line_format
 call _printf
 add esp, 16

 pop ecx
 pop edx

 sub ebx, 4
 dec edx
 loop stack_line_loop

 popf
 popa
 leave
 ret     12


sub_dump_mem:
 enter 0,0
 pusha
 pushf

 push dword [ebp+12]
 push dword [ebp+16]
 push dword mem_format1
 call _printf
 add esp, 12  
 mov esi, [ebp+12]      ; address
 and esi, 0FFFFFFF0h    ; move to start of paragraph
 mov ecx, [ebp+8]
 inc ecx
mem_outer_loop:
 push ecx
 push esi
 push dword mem_format2
 call _printf
 add esp, 8

 xor ebx, ebx
mem_hex_loop:
 xor eax, eax
 mov al, [esi + ebx]
 push eax
 push dword mem_format3
 call _printf
 add esp, 8
 inc ebx
 cmp ebx, 16
 jl mem_hex_loop

 mov eax, '"'
 call print_char
 xor ebx, ebx
mem_char_loop:
 xor eax, eax
 mov al, [esi+ebx]
 cmp al, 32
 jl non_printable
 cmp al, 126
 jg non_printable
 jmp short mem_char_loop_continue
non_printable:
 mov eax, '?'
mem_char_loop_continue:
 call print_char

 inc ebx
 cmp ebx, 16
 jl mem_char_loop

 mov eax, '"'
 call print_char
 call print_nl

 add esi, 16
 pop ecx
 loop mem_outer_loop

 popf
 popa
 leave
 ret 12

; function sub_dump_math
;   prints out state of math coprocessor without modifying the coprocessor
;   or regular processor state
; Parameters:
;  dump number - dword at [ebp+8]
; Local variables:
;   ebp-108 start of fsave buffer
;   ebp-116 temp double
; Notes: This procedure uses the Pascal convention.
;   fsave buffer structure:
;   ebp-108   control word
;   ebp-104   status word
;   ebp-100   tag word
;   ebp-80    ST0
;   ebp-70    ST1
;   ebp-60    ST2 ...
;   ebp-10    ST7
;
sub_dump_math:
 enter 116,0
 pusha
 pushf

 fsave [ebp-108] ; save coprocessor state to memory
 mov eax, [ebp-104]  ; status word
 and eax, 0FFFFh
 push eax
 mov eax, [ebp-108]  ; control word
 and eax, 0FFFFh
 push eax
 push dword [ebp+8]
 push dword math_format1
 call _printf
 add esp, 16
;
; rotate tag word so that tags in same order as numbers are
; in the stack
;
 mov cx, [ebp-104] ; ax = status word
 shr cx, 11
 and cx, 7           ; cl = physical state of number on stack top
 mov bx, [ebp-100]   ; bx = tag word
 shl     cl,1  ; cl *= 2
 ror bx, cl  ; move top of stack tag to lowest bits

 mov edi, 0  ; edi = stack number of number
 lea esi, [ebp-80]   ; esi = address of ST0
 mov ecx, 8          ; ecx = loop counter
tag_loop:
 push ecx
 mov ax, 3
 and ax, bx  ; ax = current tag
 or ax, ax  ; 00 -> valid number
 je valid_st
 cmp ax, 1  ; 01 -> zero
 je zero_st
 cmp ax, 2  ; 10 -> invalid number
 je invalid_st
 push edi  ; 11 -> empty
 push dword empty_st_format
 call _printf
 add esp, 8
 jmp short cont_tag_loop
zero_st:
 fldz
 jmp short print_real
valid_st:
 fld tword [esi]
print_real:
 fstp qword [ebp-116]
 push dword [ebp-112]
 push dword [ebp-116]
 push edi
 push dword valid_st_format
 call _printf
 add esp, 16
 jmp short cont_tag_loop
invalid_st:
 push edi
 push dword invalid_st_format
 call _printf
 add esp, 8
cont_tag_loop:
 ror bx, 2  ; mov next tag into lowest bits
 inc edi
 add esi, 10         ; mov to next number on stack
 pop ecx
 loop    tag_loop

 frstor [ebp-108]       ; restore coprocessor state
 popf
 popa
 leave
 ret 4

asm_io.inc:

 extern  read_int, print_int, print_string
 extern read_char, print_char, print_nl
 extern  sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack

%macro  dump_regs 1
 push   dword %1
 call   sub_dump_regs
%endmacro


;
; usage: dump_mem label, start-address, # paragraphs
%macro  dump_mem 3
 push  dword %1
 push  dword %2
 push  dword %3
 call  sub_dump_mem
%endmacro

%macro dump_math 1
 push  dword %1
 call  sub_dump_math
%endmacro

%macro  dump_stack 3
 push  dword %3
        push     dword %2
 push  dword %1
        call     sub_dump_stack
%endmacro

first.asm

;
; file: first.asm
; First assembly program. This program asks for two integers as
; input and prints out their sum.
;
; To create executable:
; Using djgpp:
; nasm -f coff first.asm
; gcc -o first first.o driver.c asm_io.o
;
; Using Linux and gcc:
; nasm -f elf first.asm
; gcc -o first first.o driver.c asm_io.o
;
; Using Borland C/C++
; nasm -f obj first.asm
; bcc32 first.obj driver.c asm_io.obj
;
; Using MS C/C++
; nasm -f win32 first.asm
; cl first.obj driver.c asm_io.obj
;
; Using Open Watcom
; nasm -f obj first.asm
; wcl386 first.obj driver.c asm_io.obj

%include "asm_io.inc"
;
; initialized data is put in the .data segment
;
segment .data
;
; These labels refer to strings used for output
;
prompt1 db    "Enter a number: ", 0       ; don't forget nul terminator
prompt2 db    "Enter another number: ", 0
outmsg1 db    "You entered ", 0
outmsg2 db    " and ", 0
outmsg3 db    ", the sum of these is ", 0


;
; uninitialized data is put in the .bss segment
;
segment .bss
;
; These labels refer to double words used to store the inputs
;
input1  resd 1
input2  resd 1



;
; code is put in the .text segment
;
segment .text
        global  _asm_main
_asm_main:
        enter   0,0               ; setup routine
        pusha

        mov     eax, prompt1      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input1], eax     ; store into input1

        mov     eax, prompt2      ; print out prompt
        call    print_string

        call    read_int          ; read integer
        mov     [input2], eax     ; store into input2

        mov     eax, [input1]     ; eax = dword at input1
        add     eax, [input2]     ; eax += dword at input2
        mov     ebx, eax          ; ebx = eax
        dump_regs 1               ; dump out register values
        dump_mem 2, outmsg1, 1    ; dump out memory
;
; next print out result message as series of steps
;
        mov     eax, outmsg1
        call    print_string      ; print out first message
        mov     eax, [input1]     
        call    print_int         ; print out input1
        mov     eax, outmsg2
        call    print_string      ; print out second message
        mov     eax, [input2]
        call    print_int         ; print out input2
        mov     eax, outmsg3
        call    print_string      ; print out third message
        mov     eax, ebx
        call    print_int         ; print out sum (ebx)
        call    print_nl          ; print new-line

        popa
        mov     eax, 0            ; return back to C
        leave                     
        ret

drive.c:

#include "cdecl.h"

int PRE_CDECL asm_main( void ) POST_CDECL;

int main()
{
  int ret_status;
  ret_status = asm_main();
  return ret_status;
}

Now I compile it using:

nasm -f macho first.asm

nasm -f macho asm_io.asm

gcc first.o asm_io.o driver.c -o first -arch i386

Then run:
./first

Segmentation fault

It happens only when I’m using asm_io lib.

Thank you,

Daniel Koch

  • 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-05-13T08:42:34+00:00Added an answer on May 13, 2026 at 8:42 am

    You seem to be using 32-bit assembly code here. One big difference among 32-bit Mac OS X and 32-bit Windows or Linux is that Mac requires the stack to be 16-byte aligned whenever you CALL a function. In other words, at the point in your code where you have a CALL instruction, it is required that ESP = #######0h.

    The following may be interesting reads:

    http://blogs.embarcadero.com/eboling/2009/05/20/5607

    http://www.agner.org/optimize/calling_conventions.pdf

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to loop through a bunch of documents I have to put
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
We're building an app, our first using Rails 3, and we're having to build
I'm making a simple page using Google Maps API 3. My first. One marker
I have a bunch of posts stored in text files formatted in yaml/textile (from
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have some data like this: 1 2 3 4 5 9 2 6

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.