Is Assembly Language Programming Simple?

Click For Summary

Discussion Overview

The discussion revolves around the simplicity and challenges of programming in assembly language, specifically for a project involving memory operations on a PIC microcontroller (PIC16F84). Participants explore various aspects of assembly programming, including code structure, memory manipulation, and differences between assembly languages for different architectures.

Discussion Character

  • Exploratory
  • Technical explanation
  • Homework-related
  • Debate/contested

Main Points Raised

  • One participant expresses uncertainty about the simplicity of their assembly language project, questioning whether there are tricky aspects involved in performing memory operations.
  • Another participant suggests that while the commands for memory operations are simple, understanding the overall structure of an assembly program is crucial.
  • Inline assembly is proposed as a learning method, particularly using Microsoft Visual C++ for embedding assembly code within C++ programs.
  • A participant shares their assembly code, indicating they are unsure about its correctness and struggling with memory concepts.
  • Another participant discusses the need to perform operations based on opcodes and seeks advice on how to check specific bits to determine which operation to execute.
  • Some participants note the differences between assembly languages for different architectures, with one expressing confusion about the syntax used for PIC assembly compared to x86 assembly.
  • A participant offers to share an example of a simple TASM program for 8086 to illustrate differences in assembly programming styles.

Areas of Agreement / Disagreement

Participants generally agree that assembly programming can be simple in terms of commands but recognize that understanding the structure and memory operations can be challenging. There are multiple competing views regarding the best practices for learning and coding in assembly language, and the discussion remains unresolved on certain technical aspects.

Contextual Notes

Participants express varying levels of familiarity with assembly language and specific microcontroller architectures, leading to different interpretations of assembly syntax and operations. There are unresolved questions about specific instructions and how to manipulate bits effectively.

Who May Find This Useful

This discussion may be useful for individuals learning assembly language, particularly those working with microcontrollers or transitioning from high-level programming languages to low-level programming. It may also benefit those interested in comparing assembly languages across different architectures.

mathrocks
Messages
105
Reaction score
0
I'm working on a project that I believe should be pretty simple to do if I actually knew assembly language.
For my program I'm suppose to start at data memory location 0x30 and perform the increment, decrement, complement, and clear operations. The operations are all performed on location 0x21...i.e. add 1 to location 0x21 (increment).

So given that, is this program really that simple? Or is there some tricky stuff involved?

Does anyone know of a good website to learn assembly language? And if you guys have any hints or suggestions on how I should get started with this program please help me out! I'm really just having trouble with the whole memory concepts, I'm not used to messing around with that.

Thanks!
 
Technology news on Phys.org
The best way to learn assembly is to use inlining. If you're using the Microsoft Visual C++ compiler, you can embed assembly into your C++ code like this:

PHP:
int multiplyByTwo(int a)
{
   __asm
   {
       mov eax, a
       mul eax, 2
   }
}

The return variable is left in the eax register. You can refer to C++ variables (like a) directly in the assembly instructions.

(You can inline asm with other compilers like gcc, but the syntax is much more convoluted.)

If you need a reference to the Intel x86 instruction set, the best place to go is Intel itself: ftp://download.intel.com/design/Pentium4/manuals/[/URL]

Look into the mov, inc, dec, clr and other instructions in those manuals.

If you have any more specific questions, let us know!

- Warren
 
Last edited by a moderator:
(You can inline asm with other compilers like gcc, but the syntax is much more convoluted.)
in TC (if anybody is using that now)
you have
//
asm{
mov ax,dx
};
etc
 
gnome said:
The commands to perform those memory operations are very simple, but you need to know the overall structure of an assembly language program before you can write one. Here are a couple of links:

http://www.osdata.com/topic/language/asm.htm
http://atrevida.comprenica.com/

This is my code as of now. I'm pretty sure it's totally wrong, but logically it seems right to me, increment 0x21, decrement 0x21, complement 0x21, and then clear it? I think it's just the memory stuff that's giving me a hardtime(i hope).



list P=16F84
include P16F84.INC

; Define the direction bit types
f equ 1
w equ 0

; Define the data storage locations
org 0x20
cnt res 1;the number of instructions to execute (1<=n<=8)
acc res 1 ;the accumulator


org 0x30
prg res 8 ;location of the program

; start defining the program

; no interrupts, so start at 0x0

org 0x0
goto INC

INC
org 0x30
incf 0x21, 0
goto DEC


DEC
org 0x31
decf 0x21, 0
goto COM


COM
org 0x32
comf 0x21, 0
goto CLR


CLR
org 0x33
bcf 0x21, 7
goto endless

endless nop
goto endless
end
 
Ok, I'm understanding this a little better now, my other code was totally wrong.
I'm suppose to perform the operation according to the opcode. If its 0x00 I increment, 0x01-decrement, 0x02-complement, 0x03-clear. My only question now is how do I look at the bits and see if it's a 0, 1, 2, or 3? I'm sure there's a certain operation that looks at the bits but I'm not familiar with it. This is my code thus far, I hope I'm at least on the right track.



list P=16F84
include P16F84.INC

; Define the direction bit types
f equ 1
w equ 0

; Define the data storage locations
org 0x20
cnt res 1 ;the number of instructions to execute (1<=n<=8)
acc res 1 ;the accumulator


org 0x30
prg res 8 ;location of the program

; start defining the program

; no interrupts, so start at 0x0

org 0x0
movlw 0x21
goto main

Main
*Check sign for 0x00*
goto INC

*Check sign for 0x01*
goto DEC

*Check sign for 0x02*
goto COM

*Check sign for 0x03*
goto CLR


INC
org 0x30
incf 0x21, w
goto main
DEC
org 0x31
decf 0x21, w
goto main

COM
org 0x32
comf 0x21, w
goto main

CLR
org 0x33
bcf 0x21, 7
goto endless

endless nop
goto endless
end
 
Does anyone have any suggestions?
 
What is that?

It doesn't look anything like the 80x86 assembly language I learned a couple of years ago.
 
gnome said:
What is that?

It doesn't look anything like the 80x86 assembly language I learned a couple of years ago.

I'm using assembly language to program a PIC...PIC16F84 to be specific. I don't know, I guess it can differ?
 
  • #10
I guess so. It's totally different. If you're curious, I can post an example of a simple TASM (that's Borland Turbo Assembler) program for 8086. (If not, I won't clutter up your thread.)
 
  • #11
gnome said:
I guess so. It's totally different. If you're curious, I can post an example of a simple TASM (that's Borland Turbo Assembler) program for 8086. (If not, I won't clutter up your thread.)

Yeah, that would be fine. I'm interested in seeing how different it is.
 
  • #12
Here's a pretty simple example. The stuff following the semi-colons on each line are comments, so it should be fairly easy to follow what it's doing. As you can see, much of the action involves moving data into and out of cpu registers.

Code:
% TITLE 'Arithmetic/DOS functions'



	IDEAL

	MODEL small

	STACK 100h



; equates

CR	equ	13

LF	equ	10

delimiter equ	'$'



	DATASEG

n1	dw	200

n2	dw	?

n3	dw	?

temp	dw	?

x	db	10

y	db	20

z	db	?

c	db	?

msg1	db	CR,LF," input a character",CR,LF,CR,LF,DELIMITER

msg2	db	"you pressed the character :  ",DELIMITER

msg3	db	"now the character is :  ",DELIMITER



	CODESEG

START:

	mov	ax,@data

	mov	ds,ax

	mov	ax,[n1]	;ax=n1

	sub	ax,25	;ax=ax-25 (=n1-25)

	mov	[n2],ax	;now n2=n1-25

	mov	ax,1	;ax=1

	sub	[n1],ax	;n1=n1-ax (=n1-1)

	mov	ax,[n1]	;ax=n1

	add	ax,[n2]	;ax=ax+n2 (=n1+n2)

	mov	[n3],ax	;n3=ax (=n1+n2)

	sub	[n3],10	;n3=n3-10 (=n1+n2-10)



	mov	ax,[n1]	;ax=n1

	mov	[temp],ax ;temp=ax (=n1)

	mov	bx,[n2]	;bx=n2

	mov	[n1],bx	;n1=bx (=n2)

	mov	[n2],ax	;n2=ax (=temp)

	

	mov	ah,[x]	;ah=x

	mov	al,[y]	;al=y

	sub	al,ah	;al=al-ah (=y-x)

	mov	ah,00	;ah=0

	mov	[n3],ax	;n3=ax (=(int)y-x)

	sub	[n3],1	;n3=(int)y-x-1)



	mov	ah,9	;storing DOS string output function# in ah

	mov	dx,OFFSET msg1	;stores label of string to print in dx

	int	21h	;DOS call

	mov	ah,1	;storing DOS key input function# in ah

	int	21h	;DOS call

	mov	[c],al	;retrieve char input from al register

	mov	ah,9	;storing DOS string output function# in ah

	mov	dx,OFFSET msg2	;stores label of string to print in dx

	int	21h	;DOS call

	mov	ah,2	;DOS char output function#

	mov	dl,[c]	;storing char to output in dl

	int	21h	;DOS call

	mov	dl,CR	;storing ASCII CR code in dl (function# 2 is already in ah)

	int	21h	;DOS call

	mov	dl,LF	;storing ASCII LF code in dl (function# 2 is already in ah)

	int	21h	;DOS call



	mov	bx,OFFSET c	;stores address of c in bx

	mov	al,[x]	;copies x to al (al=x)

	add	[bx],al	;add al to c (c=c+al) ([bx] is pointer to c)

	sub	[byte ptr bx],7	;subt 7 from c (c=c-7) ([bx] is pointer to c)



	mov	ah,9	;DOS string output function#

	mov	dx,OFFSET msg3	;stores label of string to print in dx

	int	21h	;DOS call

	mov	ah,2	;DOS char output function#

	mov	dl,[c]	;stores char to output (c) in dl

	int	21h	;DOS call

	mov	ah,4ch	;stores DOS terminate program function# in ah

	int	21h	;DOS call

	END	START
 
  • #13
mathrocks said:
how do I look at the bits and see if it's a 0, 1, 2, or 3?Does anyone have any suggestions?
I don't know that particular uP, but you can always use an AND instruction to test bits.
like:
AND data1,11111101b
jump_not_zero The_number_is_not_two
AND data1,00000010b
jump_not_zero Only_bit_2_on /* the value is two */
jump_zero The_value_is_zero

Notes:
Some uP will require a separate move to work register for data1.
This example requires two such moves since the first test is destructive.

Other uP put the result in a work register.
In this case the test is not destructive.

Almost all uP will set the zero flag on an AND without a separate compare instruction.

You need to learn the available instructions in order to be effcient.
Some uP have specific instructions to test bits.
 
  • #14
...and most people (including me) will assume that you're talking about x86 assembly unless you specify otherwise. :smile:

- Warren
 
  • #15
Take Chroot’s recommendation and go to Intel and read their manual. Whether it is worth your while learning an assembly language depends on your interests, your job, and the people you will be working with. If you are working with engineers building embedded systems, or designing embedded system yourself, I’d say it would be a very good idea to be familiar with the assembly language of the microcontrollers that you or they are working with.
 
  • #16
Sorry...The above response was to another thread that I pasted in the wrong place..
 
  • #17
i don't really know, one thing that's amazing is that i know assembly and I am only 11. Here are sites i visited to help, Art of assembly, emu8086, fasm, osdev, intel. But who cares what sites. did you know i learned some imaginary assembly then i jmped when i saw real assembly(not real-mode, x86 assembly)
 
  • #18
I need a list of all IO port numbers
 
  • #19
TudorOSasker said:
I need a list of all IO port numbers

First: Don't hijack threads; start a new one for a new topic.

Second: See RBIL or HelpPC.
 

Similar threads

  • · Replies 122 ·
5
Replies
122
Views
17K
Replies
16
Views
4K
  • · Replies 5 ·
Replies
5
Views
4K
Replies
6
Views
3K
Replies
12
Views
4K
  • · Replies 1 ·
Replies
1
Views
4K
  • · Replies 4 ·
Replies
4
Views
5K
  • · Replies 6 ·
Replies
6
Views
3K
  • Sticky
  • · Replies 13 ·
Replies
13
Views
8K