diff --git a/bincopy.py b/bincopy.py
index c26b486..fbe3ba5 100755
--- a/bincopy.py
+++ b/bincopy.py
@@ -361,22 +361,39 @@ class Segment:
     def address(self):
         return self.minimum_address // self.word_size_bytes
 
-    def chunks(self, size=32, alignment=1):
-        """Return chunks of the data aligned as given by `alignment`. `size`
-        must be a multiple of `alignment`. Each chunk is itself a Segment.
-        Both `size` and `alignment` are in words.
+    def chunks(self, size=32, alignment=1, padding=b''):
+        """Yield data chunks of `size` words, aligned as given by `alignment`.
+
+        Each chunk is itself a Segment.
+
+        `size` and `alignment` are in words. `size` must be a multiple of
+        `alignment`. If set, `padding` must be a word value.
+
+        If `padding` is set, the first and final chunks are padded so that:
+            1. The first chunk is aligned even if the segment itself is not.
+            2. The final chunk's size is a multiple of `alignment`.
 
         """
 
         if (size % alignment) != 0:
             raise Error(f'size {size} is not a multiple of alignment {alignment}')
 
+        if padding and len(padding) != self.word_size_bytes:
+            raise Error(f'padding must be a word value (size {self.word_size_bytes}),'
+                        f' got {padding}')
+
         size *= self.word_size_bytes
         alignment *= self.word_size_bytes
         address = self.minimum_address
         data = self.data
 
-        # First chunk may be shorter than `size` due to alignment.
+        # Apply padding to first and final chunk, if padding is non-empty.
+        align_offset = address % alignment
+        address -= align_offset * bool(padding)
+        data = align_offset // self.word_size_bytes * padding + data
+        data += (alignment - len(data)) % alignment // self.word_size_bytes * padding
+
+        # First chunk may be non-aligned and shorter than `size` if padding is empty.
         chunk_offset = (address % alignment)
 
         if chunk_offset != 0:
@@ -632,21 +649,51 @@ class Segments:
 
         self._list = new_list
 
-    def chunks(self, size=32, alignment=1):
-        """Iterate over all segments and return chunks of the data aligned as
-        given by `alignment`. `size` must be a multiple of
-        `alignment`. Each chunk is in turn a smaller Segment. Both `size` and
-        `alignment` are in words.
+    def chunks(self, size=32, alignment=1, padding=b''):
+        """Iterate over all segments and yield chunks of the data.
+        
+        The chunks are `size` words long, aligned as given by `alignment`.
+
+        Each chunk is itself a Segment.
+
+        `size` and `alignment` are in words. `size` must be a multiple of
+        `alignment`. If set, `padding` must be a word value.
+
+        If `padding` is set, the first and final chunks of each segment are
+        padded so that:
+            1. The first chunk is aligned even if the segment itself is not.
+            2. The final chunk's size is a multiple of `alignment`.
 
         """
 
         if (size % alignment) != 0:
             raise Error(f'size {size} is not a multiple of alignment {alignment}')
 
+        if padding and len(padding) != self.word_size_bytes:
+            raise Error(f'padding must be a word value (size {self.word_size_bytes}),'
+                        f' got {padding}')
+
+        previous = Segment(-1, -1, b'', 1)
+
         for segment in self:
-            for chunk in segment.chunks(size, alignment):
+            for chunk in segment.chunks(size, alignment, padding):
+                # When chunks are padded to alignment, the final chunk of the previous
+                # segment and the first chunk of the current segment may overlap by
+                # one alignment block. To avoid overwriting data from the lower
+                # segment, the chunks must be merged.
+                if chunk.address < previous.address + len(previous):
+                    low = previous.data[-alignment * self.word_size_bytes:]
+                    high = chunk.data[:alignment * self.word_size_bytes]
+                    merged = int.to_bytes(int.from_bytes(low, 'big') ^
+                                          int.from_bytes(high, 'big') ^
+                                          int.from_bytes(alignment * padding, 'big'),
+                                          alignment * self.word_size_bytes, 'big')
+                    chunk.data = merged + chunk.data[alignment * self.word_size_bytes:]
+
                 yield chunk
 
+            previous = chunk
+
     def __len__(self):
         """Get the number of segments.
 

diff --git a/tests/test_bincopy.py b/tests/test_bincopy.py
index 3a81584..945086a 100644
--- a/tests/test_bincopy.py
+++ b/tests/test_bincopy.py
@@ -910,6 +910,12 @@ class BinCopyTest(unittest.TestCase):
         self.assertEqual(str(cm.exception),
                          'size 4 is not a multiple of alignment 8')
 
+        with self.assertRaises(bincopy.Error) as cm:
+            list(binfile.segments.chunks(padding=b'\xff\xff'))
+
+        self.assertEqual(str(cm.exception),
+                         r"padding must be a word value (size 1), got b'\xff\xff'")
+
     def test_segment(self):
         binfile = bincopy.BinFile()
         binfile.add_binary(b'\x00\x01\x02\x03\x04', 2)
@@ -1863,6 +1869,44 @@ Data ranges:
         first_word = int.from_bytes(binfile[:binfile.minimum_address + 1], 'little')
         self.assertEqual(0xC9E4, first_word)
 
+    def test_chunk_padding(self):
+        records = (':02000004000AF0\n'
+                   ':10B8440000000000000000009630000007770000B0\n')
+        hexfile = bincopy.BinFile()
+        hexfile.add_ihex(records)
+        align = 8
+        size = 16
+        chunks = hexfile.segments.chunks(size=size, alignment=align, padding=b'\xff')
+        chunks = list(chunks)
+        assert not any(c.address % align for c in chunks)
+        assert not any(len(c) % align for c in chunks)
+
+    def test_merge_chunks(self):
+        records = (':0A0000001010101010101010101056\n'
+                   ':0A000E001010101010101010101048\n')
+        hexfile = bincopy.BinFile()
+        hexfile.add_ihex(records)
+        align = 8
+        size = 16
+        chunks = hexfile.segments.chunks(size=size, alignment=align, padding=b'\xff')
+        chunks = list(chunks)
+        assert list(chunks[-1]) == [8, b'\x10\x10\xff\xff\xff\xff\x10\x10\x10\x10\x10'
+                                       b'\x10\x10\x10\x10\x10']
+
+    def test_merge_chunks_16(self):
+        records = (':1000000010101010101010101010101010101010F0\n'
+                   ':10000A0010101010101010101010101010101010E6\n')
+        hexfile = bincopy.BinFile(word_size_bits=16)
+        hexfile.add_ihex(records)
+        align = 6
+        size = 12
+        chunks = hexfile.segments.chunks(size=size, alignment=align,
+                                         padding=b'\xff\xff')
+        chunks = list(chunks)
+        assert list(chunks[-1]) == [6, b'\x10\x10\x10\x10\xff\xff\xff\xff\x10\x10\x10'
+                                       b'\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'
+                                       b'\x10\x10']
+
 
 if __name__ == '__main__':
     unittest.main()

First chunk is misaligned if segment has non-aligned start address
```python
records = """
    :02000004000AF0
    :10B8440000000000000000009630000007770000B0
"""
hexfile = bincopy.BinFile()
hexfile.add_ihex(records)
align = 8
chunks = hexfile.segments.chunks(size=16, alignment=align)
assert not any(c.address % align for c in chunks)
```

IMO, the first chunk should be padded such that it is also aligned.
tests/test_bincopy.py::BinCopyTest::test_chunk_padding tests/test_bincopy.py::BinCopyTest::test_chunks_bad_arguments tests/test_bincopy.py::BinCopyTest::test_merge_chunks tests/test_bincopy.py::BinCopyTest::test_merge_chunks_16
tests/test_bincopy.py::BinCopyTest::test_add tests/test_bincopy.py::BinCopyTest::test_add_elf tests/test_bincopy.py::BinCopyTest::test_add_elf_blinky tests/test_bincopy.py::BinCopyTest::test_add_elf_gcc tests/test_bincopy.py::BinCopyTest::test_add_elf_iar tests/test_bincopy.py::BinCopyTest::test_add_elf_keil tests/test_bincopy.py::BinCopyTest::test_add_file tests/test_bincopy.py::BinCopyTest::test_add_files tests/test_bincopy.py::BinCopyTest::test_add_ihex_bad_record_type_6 tests/test_bincopy.py::BinCopyTest::test_add_ihex_record_type_3 tests/test_bincopy.py::BinCopyTest::test_add_ihex_record_type_5 tests/test_bincopy.py::BinCopyTest::test_add_microchip_hex_record tests/test_bincopy.py::BinCopyTest::test_array tests/test_bincopy.py::BinCopyTest::test_as_ihex_bad_address_length_bits tests/test_bincopy.py::BinCopyTest::test_as_srec_bad_address_length tests/test_bincopy.py::BinCopyTest::test_as_srec_record_5 tests/test_bincopy.py::BinCopyTest::test_as_srec_record_6 tests/test_bincopy.py::BinCopyTest::test_as_srec_record_8 tests/test_bincopy.py::BinCopyTest::test_bad_ihex tests/test_bincopy.py::BinCopyTest::test_bad_srec tests/test_bincopy.py::BinCopyTest::test_bad_ti_txt tests/test_bincopy.py::BinCopyTest::test_bad_word_size tests/test_bincopy.py::BinCopyTest::test_binary tests/test_bincopy.py::BinCopyTest::test_binary_16 tests/test_bincopy.py::BinCopyTest::test_chunks_list tests/test_bincopy.py::BinCopyTest::test_command_line_convert_elf tests/test_bincopy.py::BinCopyTest::test_command_line_convert_input_formats tests/test_bincopy.py::BinCopyTest::test_command_line_convert_output_format_binary tests/test_bincopy.py::BinCopyTest::test_command_line_convert_output_format_binary_bad_addresses tests/test_bincopy.py::BinCopyTest::test_command_line_convert_output_formats tests/test_bincopy.py::BinCopyTest::test_command_line_convert_output_formats_bad_parameters tests/test_bincopy.py::BinCopyTest::test_command_line_convert_overlapping tests/test_bincopy.py::BinCopyTest::test_command_line_convert_overwrite tests/test_bincopy.py::BinCopyTest::test_command_line_dump_commands_one_file tests/test_bincopy.py::BinCopyTest::test_command_line_fill tests/test_bincopy.py::BinCopyTest::test_command_line_fill_max_words tests/test_bincopy.py::BinCopyTest::test_command_line_fill_outfile tests/test_bincopy.py::BinCopyTest::test_command_line_fill_stdout tests/test_bincopy.py::BinCopyTest::test_command_line_fill_value tests/test_bincopy.py::BinCopyTest::test_command_line_info_one_file tests/test_bincopy.py::BinCopyTest::test_command_line_info_one_file_16_bits_words tests/test_bincopy.py::BinCopyTest::test_command_line_info_two_files tests/test_bincopy.py::BinCopyTest::test_command_line_info_two_files_with_header_encoding tests/test_bincopy.py::BinCopyTest::test_command_line_non_existing_file tests/test_bincopy.py::BinCopyTest::test_command_line_non_existing_file_debug tests/test_bincopy.py::BinCopyTest::test_command_line_pretty tests/test_bincopy.py::BinCopyTest::test_compare_ti_txt tests/test_bincopy.py::BinCopyTest::test_exclude_crop tests/test_bincopy.py::BinCopyTest::test_exclude_edge_cases tests/test_bincopy.py::BinCopyTest::test_execution_start_address tests/test_bincopy.py::BinCopyTest::test_fill tests/test_bincopy.py::BinCopyTest::test_fill_max_words tests/test_bincopy.py::BinCopyTest::test_fill_word_size_16 tests/test_bincopy.py::BinCopyTest::test_header_default_encoding tests/test_bincopy.py::BinCopyTest::test_header_no_encoding tests/test_bincopy.py::BinCopyTest::test_hexdump_1 tests/test_bincopy.py::BinCopyTest::test_hexdump_2 tests/test_bincopy.py::BinCopyTest::test_hexdump_empty tests/test_bincopy.py::BinCopyTest::test_hexdump_gaps tests/test_bincopy.py::BinCopyTest::test_i16hex tests/test_bincopy.py::BinCopyTest::test_i16hex_address_above_1meg tests/test_bincopy.py::BinCopyTest::test_i32hex tests/test_bincopy.py::BinCopyTest::test_i32hex_address_above_4gig tests/test_bincopy.py::BinCopyTest::test_i8hex tests/test_bincopy.py::BinCopyTest::test_i8hex_address_above_64k tests/test_bincopy.py::BinCopyTest::test_ignore_blank_lines_hex tests/test_bincopy.py::BinCopyTest::test_ignore_blank_lines_srec tests/test_bincopy.py::BinCopyTest::test_ihex tests/test_bincopy.py::BinCopyTest::test_ihex_crc tests/test_bincopy.py::BinCopyTest::test_info tests/test_bincopy.py::BinCopyTest::test_init_files tests/test_bincopy.py::BinCopyTest::test_issue_4_1 tests/test_bincopy.py::BinCopyTest::test_issue_4_2 tests/test_bincopy.py::BinCopyTest::test_iterate_segments tests/test_bincopy.py::BinCopyTest::test_layout_empty_main tests/test_bincopy.py::BinCopyTest::test_layout_in_exclude_2_4 tests/test_bincopy.py::BinCopyTest::test_layout_out tests/test_bincopy.py::BinCopyTest::test_minimum_maximum_length tests/test_bincopy.py::BinCopyTest::test_non_sorted_segments tests/test_bincopy.py::BinCopyTest::test_overwrite tests/test_bincopy.py::BinCopyTest::test_performance tests/test_bincopy.py::BinCopyTest::test_print tests/test_bincopy.py::BinCopyTest::test_segment tests/test_bincopy.py::BinCopyTest::test_segment_len tests/test_bincopy.py::BinCopyTest::test_segment_len_16 tests/test_bincopy.py::BinCopyTest::test_segments_list tests/test_bincopy.py::BinCopyTest::test_set_get_item tests/test_bincopy.py::BinCopyTest::test_set_get_item_16 tests/test_bincopy.py::BinCopyTest::test_srec tests/test_bincopy.py::BinCopyTest::test_srec_ihex_binary tests/test_bincopy.py::BinCopyTest::test_srec_no_header_encoding tests/test_bincopy.py::BinCopyTest::test_ti_txt tests/test_bincopy.py::BinCopyTest::test_verilog_vmem tests/test_bincopy.py::BinCopyTest::test_word_size tests/test_bincopy.py::BinCopyTest::test_word_size_custom_padding tests/test_bincopy.py::BinCopyTest::test_word_size_default_padding